<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>class RubyVM::RJIT::InsnCompiler - ruby_vm: Ruby Standard Library Documentation</title>


<script src="../../js/navigation.js" defer></script>
<script src="../../js/search.js" defer></script>
<script src="../../js/search_index.js" defer></script>
<script src="../../js/searcher.js" defer></script>
<script src="../../js/darkfish.js" defer></script>

<script src="../../js/jquery-3.2.0.min.js"></script>

<script src="../../js/vue.min.js"></script>
<script src="../../js/js.cookie.min.js"></script>

<link href="../../css/fonts.css" rel="stylesheet">
<link id='rdoccss' href="../../css/rdoc.css" rel="stylesheet">
<link href="../../css/carbon17.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "../../";
  var index_rel_prefix = "../../";
  var darkModeCsseHref = "../../css/rdoc-dm.css"
  var defaultModeCssHref = "../../css/rdoc.css"
  // var cssDarkmode = Cookies.get('darkmode');
  
  if( Cookies.get("darkmode") == "true") {
	$('#rdoccss').attr("href", darkModeCsseHref);
}

//  https://cssdeck.com/blog/simple-jquery-stylesheet-switcher/

document.write('<style type="text/css">body{display:none}</style>');

</script>


</head>
<body id="top" role="document" class="class">
  <!-- this is class.html -->

  <div id='actionbar' >
    <div class='wrapper mdiv'>
      <ul class='grids g0'></ul>
    </div> 
    <!-- VERSION HEADER for 3.3.0.preview2 NOT FOUND -->
  </div> <!-- end action bar -->

  <div class='wrapper hdiv'>

    


    <nav id='vapp' role="navigation">
    <div id="project-navigation">
      <div id="home-section" role="region" title="Quick navigation" class="nav-section">
  <h2><a href="../../index.html" rel="home">Home</a></h2>

  <div id="table-of-contents-navigation"  >
    <a href="../../table_of_contents.html#pages">Pages</a>
    <a href="../../table_of_contents.html#classes">Classes</a>
    <a href="../../table_of_contents.html#methods">Methods</a>
  </div>
</div>

      <div id="search-section" role="search" class="project-section initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <div id="search-field-wrapper">
      <input id="search-field" role="combobox" aria-label="Search"
             aria-autocomplete="list" aria-controls="search-results"
             type="text" name="search" placeholder="Search" spellcheck="false"
             title="Type to search, Up and Down to navigate, Enter to load">
    </div>

    <ul id="search-results" aria-label="Search Results"
        aria-busy="false" aria-expanded="false"
        aria-atomic="false" class="initially-hidden"></ul>
  </form>
</div>

    </div>


    

    <button id='toggleThing' @click="toggleNav()" >Show/hide navigation</button>
    <div :class="isOpen ? 'block' : 'hidden' " id='toggleMe'>
      <div id="class-metadata">
        
        
<div id="parent-class-section" class="nav-section">
  <h3>Parent</h3>

  <p class="link">Object
</div>

        
        
        
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
  <h3>Methods</h3>

  <ul class="link-list" role="directory">
    <li ><a href="#method-i-assert">#assert</a>
    <li ><a href="#method-i-assert_equal">#assert_equal</a>
    <li ><a href="#method-i-build_calling">#build_calling</a>
    <li ><a href="#method-i-builtin_function">#builtin_function</a>
    <li ><a href="#method-i-c_method_tracing_currently_enabled-3F">#c_method_tracing_currently_enabled?</a>
    <li ><a href="#method-i-counted_exit">#counted_exit</a>
    <li ><a href="#method-i-def_iseq_ptr">#def_iseq_ptr</a>
    <li ><a href="#method-i-defer_compilation">#defer_compilation</a>
    <li ><a href="#method-i-dynamic_symbol-3F">#dynamic_symbol?</a>
    <li ><a href="#method-i-fixnum-3F">#fixnum?</a>
    <li ><a href="#method-i-flonum-3F">#flonum?</a>
    <li ><a href="#method-i-full_cfunc_return">#full_cfunc_return</a>
    <li ><a href="#method-i-guard_block_arg">#guard_block_arg</a>
    <li ><a href="#method-i-handle_opt_send_shift_stack">#handle_opt_send_shift_stack</a>
    <li ><a href="#method-i-jit_array_len">#jit_array_len</a>
    <li ><a href="#method-i-jit_array_ptr">#jit_array_ptr</a>
    <li ><a href="#method-i-jit_call_alias">#jit_call_alias</a>
    <li ><a href="#method-i-jit_call_attrset">#jit_call_attrset</a>
    <li ><a href="#method-i-jit_call_bmethod">#jit_call_bmethod</a>
    <li ><a href="#method-i-jit_call_cfunc">#jit_call_cfunc</a>
    <li ><a href="#method-i-jit_call_general">#jit_call_general</a>
    <li ><a href="#method-i-jit_call_iseq">#jit_call_iseq</a>
    <li ><a href="#method-i-jit_call_ivar">#jit_call_ivar</a>
    <li ><a href="#method-i-jit_call_method">#jit_call_method</a>
    <li ><a href="#method-i-jit_call_method_each_type">#jit_call_method_each_type</a>
    <li ><a href="#method-i-jit_call_opt_call">#jit_call_opt_call</a>
    <li ><a href="#method-i-jit_call_opt_send">#jit_call_opt_send</a>
    <li ><a href="#method-i-jit_call_opt_struct_aref">#jit_call_opt_struct_aref</a>
    <li ><a href="#method-i-jit_call_optimized">#jit_call_optimized</a>
    <li ><a href="#method-i-jit_call_symbol">#jit_call_symbol</a>
    <li ><a href="#method-i-jit_caller_setup_arg">#jit_caller_setup_arg</a>
    <li ><a href="#method-i-jit_direct_jump">#jit_direct_jump</a>
    <li ><a href="#method-i-jit_get_ep">#jit_get_ep</a>
    <li ><a href="#method-i-jit_get_lep">#jit_get_lep</a>
    <li ><a href="#method-i-jit_getivar">#jit_getivar</a>
    <li ><a href="#method-i-jit_leaf_builtin_func">#jit_leaf_builtin_func</a>
    <li ><a href="#method-i-jit_protected_callee_ancestry_guard">#jit_protected_callee_ancestry_guard</a>
    <li ><a href="#method-i-jit_push_frame">#jit_push_frame</a>
    <li ><a href="#method-i-jit_search_method">#jit_search_method</a>
    <li ><a href="#method-i-jit_write_iv">#jit_write_iv</a>
    <li ><a href="#method-i-move_rest_args_to_stack">#move_rest_args_to_stack</a>
    <li ><a href="#method-i-push_splat_args">#push_splat_args</a>
    <li ><a href="#method-i-shape_too_complex-3F">#shape_too_complex?</a>
    <li ><a href="#method-i-side_exit">#side_exit</a>
    <li ><a href="#method-i-static_symbol-3F">#static_symbol?</a>
    <li ><a href="#method-i-symbol-3F">#symbol?</a>
    <li ><a href="#method-i-to_value">#to_value</a>
  </ul>
</div>

      </div>
     </div>
    </nav>


    <div id='extraz'><div class='adzbox-index'  >
      
     </div>         
    </div>

    <main role="main" aria-labelledby="class-RubyVM::RJIT::InsnCompiler">
    <h1 id="class-RubyVM::RJIT::InsnCompiler" class="class">
      class RubyVM::RJIT::InsnCompiler
    </h1>

    <section class="description">
    
    </section>

      <section id="5Buntitled-5D" class="documentation-section">


      <section class="constants-list">
      <header>
      <h3>Constants</h3>
      </header>
      <dl>
          <dt id="CallingInfo">CallingInfo
          <dd><p>struct rb_calling_info. Storing flags instead of ci.</p>
        </dl>
        </section>



                <section id="public-instance-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Instance Methods</h3>
                </header>

                  <div id="method-i-assert" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">assert</span><span
                                class="method-args">(cond)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="assert-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5830</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">assert</span>(<span class="ruby-identifier">cond</span>)
  <span class="ruby-identifier">assert_equal</span>(<span class="ruby-identifier">cond</span>, <span class="ruby-keyword">true</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-assert_equal" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">assert_equal</span><span
                                class="method-args">(left, right)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="assert_equal-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5834</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">assert_equal</span>(<span class="ruby-identifier">left</span>, <span class="ruby-identifier">right</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">left</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">right</span>
    <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;&#39;#{left.inspect}&#39; was not &#39;#{right.inspect}&#39;&quot;</span>
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-build_calling" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">build_calling</span><span
                                class="method-args">(ci:, block_handler:)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="build_calling-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5953</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">build_calling</span>(<span class="ruby-value">ci:</span>, <span class="ruby-value">block_handler:</span>)
  <span class="ruby-constant">CallingInfo</span>.<span class="ruby-identifier">new</span>(
    <span class="ruby-value">argc:</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">vm_ci_argc</span>(<span class="ruby-identifier">ci</span>),
    <span class="ruby-value">flags:</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">vm_ci_flag</span>(<span class="ruby-identifier">ci</span>),
    <span class="ruby-value">kwarg:</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">vm_ci_kwarg</span>(<span class="ruby-identifier">ci</span>),
    <span class="ruby-value">ci_addr:</span> <span class="ruby-identifier">ci</span>.<span class="ruby-identifier">to_i</span>,
    <span class="ruby-value">send_shift:</span> <span class="ruby-value">0</span>,
    <span class="ruby-value">block_handler:</span>,
  )
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-builtin_function" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">builtin_function</span><span
                                class="method-args">(iseq)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Return a builtin function if a given iseq consists of only that builtin function</p>

                              <div class="method-source-code" id="builtin_function-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5943</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">builtin_function</span>(<span class="ruby-identifier">iseq</span>)
  <span class="ruby-identifier">opt_invokebuiltin_delegate_leave</span> = <span class="ruby-constant">INSNS</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">find</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span> <span class="ruby-identifier">i</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-value">:opt_invokebuiltin_delegate_leave</span> }
  <span class="ruby-identifier">leave</span> = <span class="ruby-constant">INSNS</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">find</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span> <span class="ruby-identifier">i</span>.<span class="ruby-identifier">name</span> <span class="ruby-operator">==</span> <span class="ruby-value">:leave</span> }
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">iseq_size</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">opt_invokebuiltin_delegate_leave</span>.<span class="ruby-identifier">len</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">leave</span>.<span class="ruby-identifier">len</span> <span class="ruby-operator">&amp;&amp;</span>
      <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_vm_insn_decode</span>(<span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">iseq_encoded</span>[<span class="ruby-value">0</span>]) <span class="ruby-operator">==</span> <span class="ruby-identifier">opt_invokebuiltin_delegate_leave</span>.<span class="ruby-identifier">bin</span> <span class="ruby-operator">&amp;&amp;</span>
      <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_vm_insn_decode</span>(<span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">iseq_encoded</span>[<span class="ruby-identifier">opt_invokebuiltin_delegate_leave</span>.<span class="ruby-identifier">len</span>]) <span class="ruby-operator">==</span> <span class="ruby-identifier">leave</span>.<span class="ruby-identifier">bin</span>
    <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_builtin_function</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">iseq_encoded</span>[<span class="ruby-value">1</span>])
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-c_method_tracing_currently_enabled-3F" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">c_method_tracing_currently_enabled?</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="c_method_tracing_currently_enabled-3F-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5938</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">c_method_tracing_currently_enabled?</span>
  <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_rjit_global_events</span> <span class="ruby-operator">&amp;</span> (<span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_EVENT_C_CALL</span> <span class="ruby-operator">|</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_EVENT_C_RETURN</span>) <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-counted_exit" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">counted_exit</span><span
                                class="method-args">(side_exit, name)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="counted_exit-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5915</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">counted_exit</span>(<span class="ruby-identifier">side_exit</span>, <span class="ruby-identifier">name</span>)
  <span class="ruby-identifier">asm</span> = <span class="ruby-constant">Assembler</span>.<span class="ruby-identifier">new</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-identifier">name</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">jmp</span>(<span class="ruby-identifier">side_exit</span>)
  <span class="ruby-ivar">@ocb</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">asm</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-def_iseq_ptr" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">def_iseq_ptr</span><span
                                class="method-args">(cme_def)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="def_iseq_ptr-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5922</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">def_iseq_ptr</span>(<span class="ruby-identifier">cme_def</span>)
  <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_iseq_check</span>(<span class="ruby-identifier">cme_def</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">iseqptr</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-defer_compilation" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">defer_compilation</span><span
                                class="method-args">(jit, ctx, asm)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>@param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="defer_compilation-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5868</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">defer_compilation</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-comment"># Make a stub to compile the current insn</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">chain_depth</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">raise</span> <span class="ruby-string">&quot;double defer!&quot;</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">chain_depth</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
  <span class="ruby-identifier">jit_direct_jump</span>(<span class="ruby-identifier">jit</span>.<span class="ruby-identifier">iseq</span>, <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">pc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-value">comment:</span> <span class="ruby-string">&#39;defer_compilation&#39;</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-dynamic_symbol-3F" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">dynamic_symbol?</span><span
                                class="method-args">(obj)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="dynamic_symbol-3F-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5856</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">dynamic_symbol?</span>(<span class="ruby-identifier">obj</span>)
  <span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span> <span class="ruby-keyword">if</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">SPECIAL_CONST_P</span>(<span class="ruby-identifier">obj</span>)
  <span class="ruby-constant">C</span>.<span class="ruby-constant">RB_TYPE_P</span>(<span class="ruby-identifier">obj</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_T_SYMBOL</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-fixnum-3F" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">fixnum?</span><span
                                class="method-args">(obj)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="fixnum-3F-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5840</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">fixnum?</span>(<span class="ruby-identifier">obj</span>)
  (<span class="ruby-constant">C</span>.<span class="ruby-identifier">to_value</span>(<span class="ruby-identifier">obj</span>) <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_FIXNUM_FLAG</span>) <span class="ruby-operator">==</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_FIXNUM_FLAG</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-flonum-3F" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">flonum?</span><span
                                class="method-args">(obj)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="flonum-3F-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5844</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">flonum?</span>(<span class="ruby-identifier">obj</span>)
  (<span class="ruby-constant">C</span>.<span class="ruby-identifier">to_value</span>(<span class="ruby-identifier">obj</span>) <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_FLONUM_MASK</span>) <span class="ruby-operator">==</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_FLONUM_FLAG</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-full_cfunc_return" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">full_cfunc_return</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="full_cfunc_return-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5931</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">full_cfunc_return</span>
  <span class="ruby-ivar">@full_cfunc_return</span> <span class="ruby-operator">||=</span> <span class="ruby-constant">Assembler</span>.<span class="ruby-identifier">new</span>.<span class="ruby-identifier">then</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">asm</span><span class="ruby-operator">|</span>
    <span class="ruby-ivar">@exit_compiler</span>.<span class="ruby-identifier">compile_full_cfunc_return</span>(<span class="ruby-identifier">asm</span>)
    <span class="ruby-ivar">@ocb</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">asm</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-guard_block_arg" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">guard_block_arg</span><span
                                class="method-args">(jit, ctx, asm, calling)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_caller_setup_arg_block: Handle VM_CALL_ARGS_BLOCKARG cases. @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="guard_block_arg-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4188</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">guard_block_arg</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">block_arg_type</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">get_opnd_type</span>(<span class="ruby-constant">StackOpnd</span>[<span class="ruby-value">0</span>])
    <span class="ruby-keyword">case</span> <span class="ruby-identifier">block_arg_type</span>
    <span class="ruby-keyword">in</span> <span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Nil</span>
      <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span> = <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_BLOCK_HANDLER_NONE</span>
    <span class="ruby-keyword">in</span> <span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">BlockParamProxy</span>
      <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_block_param_proxy</span>
    <span class="ruby-keyword">else</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_block_arg</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-handle_opt_send_shift_stack" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">handle_opt_send_shift_stack</span><span
                                class="method-args">(asm, argc, ctx, send_shift:)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_opt_send (lazy part) @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="handle_opt_send_shift_stack-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5477</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">handle_opt_send_shift_stack</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-value">send_shift:</span>)
  <span class="ruby-comment"># We don&#39;t support `send(:send, ...)` for now.</span>
  <span class="ruby-identifier">assert_equal</span>(<span class="ruby-value">1</span>, <span class="ruby-identifier">send_shift</span>)

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;shift stack&#39;</span>)
  (<span class="ruby-value">0</span><span class="ruby-operator">...</span><span class="ruby-identifier">argc</span>).<span class="ruby-identifier">reverse_each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">i</span>)
    <span class="ruby-identifier">opnd2</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">i</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">opnd</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">opnd2</span>, <span class="ruby-value">:rax</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">shift_stack</span>(<span class="ruby-identifier">argc</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_array_len" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_array_len</span><span
                                class="method-args">(asm, array_reg, len_reg)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Generate RARRAY_LEN. For array_opnd, use Opnd::Reg to reduce memory access, and use Opnd::Mem to save registers.</p>

                              <div class="method-source-code" id="jit_array_len-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5800</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_array_len</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">array_reg</span>, <span class="ruby-identifier">len_reg</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;get array length for embedded or heap&#39;</span>)

  <span class="ruby-comment"># Pull out the embed flag to check if it&#39;s an embedded array.</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">len_reg</span>, [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RBasic</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:flags</span>)])

  <span class="ruby-comment"># Get the length of the array</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">and</span>(<span class="ruby-identifier">len_reg</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RARRAY_EMBED_LEN_MASK</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">sar</span>(<span class="ruby-identifier">len_reg</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RARRAY_EMBED_LEN_SHIFT</span>)

  <span class="ruby-comment"># Conditionally move the length of the heap array</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">test</span>([<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RBasic</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:flags</span>)], <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RARRAY_EMBED_FLAG</span>)

  <span class="ruby-comment"># Select the array length value</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmovz</span>(<span class="ruby-identifier">len_reg</span>, [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RArray</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:heap</span>, <span class="ruby-value">:len</span>)])
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_array_ptr" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_array_ptr</span><span
                                class="method-args">(asm, array_reg, ary_opnd)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Generate RARRAY_CONST_PTR (part of RARRAY_AREF)</p>

                              <div class="method-source-code" id="jit_array_ptr-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5818</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_array_ptr</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">array_reg</span>, <span class="ruby-identifier">ary_opnd</span>) <span class="ruby-comment"># clobbers array_reg</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;get array pointer for embedded or heap&#39;</span>)

  <span class="ruby-identifier">flags_opnd</span> = [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RBasic</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:flags</span>)]
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">test</span>(<span class="ruby-identifier">flags_opnd</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RARRAY_EMBED_FLAG</span>)
  <span class="ruby-comment"># Load the address of the embedded array</span>
  <span class="ruby-comment"># (struct RArray *)(obj)-&gt;as.ary</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">ary_opnd</span>, [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RArray</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:heap</span>, <span class="ruby-value">:ptr</span>)])
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-identifier">array_reg</span>, [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RArray</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:ary</span>)]) <span class="ruby-comment"># clobbers array_reg</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmovnz</span>(<span class="ruby-identifier">ary_opnd</span>, <span class="ruby-identifier">array_reg</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_alias" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_alias</span><span
                                class="method-args">(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_alias @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_alias-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5314</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_alias</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-identifier">cme</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_aliased_callable_method_entry</span>(<span class="ruby-identifier">cme</span>)
  <span class="ruby-identifier">jit_call_method_each_type</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-identifier">known_recv_class</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_attrset" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_attrset</span><span
                                class="method-args">(jit, ctx, asm, cme, calling, comptime_recv, recv_opnd)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_attrset @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_attrset-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5184</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_attrset</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>)
  <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>
  <span class="ruby-identifier">flags</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span>
  <span class="ruby-identifier">send_shift</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_attrset_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KWARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_attrset_kwarg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">argc</span> <span class="ruby-operator">!=</span> <span class="ruby-value">1</span> <span class="ruby-operator">||</span> <span class="ruby-operator">!</span><span class="ruby-constant">C</span>.<span class="ruby-constant">RB_TYPE_P</span>(<span class="ruby-identifier">comptime_recv</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_T_OBJECT</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_attrset_method</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">c_method_tracing_currently_enabled?</span>
    <span class="ruby-comment"># Can&#39;t generate code for firing c_call and c_return events</span>
    <span class="ruby-comment"># See :attr-tracing:</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_c_tracingg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_block_arg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">ivar_name</span> = <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">attr</span>.<span class="ruby-identifier">id</span>

  <span class="ruby-comment"># This is a .send call and we need to adjust the stack</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">handle_opt_send_shift_stack</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-value">send_shift:</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Save the PC and SP because the callee may allocate</span>
  <span class="ruby-comment"># Note that this modifies REG_SP, which is why we do it first</span>
  <span class="ruby-identifier">jit_prepare_routine_call</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)

  <span class="ruby-comment"># Get the operands from the stack</span>
  <span class="ruby-identifier">val_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-value">1</span>)
  <span class="ruby-identifier">recv_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-value">1</span>)

  <span class="ruby-comment"># Call rb_vm_set_ivar_id with the receiver, the ivar name, and the value</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">recv_opnd</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">ivar_name</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">2</span>], <span class="ruby-identifier">val_opnd</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_vm_set_ivar_id</span>)

  <span class="ruby-identifier">out_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">out_opnd</span>, <span class="ruby-constant">C_RET</span>)

  <span class="ruby-constant">KeepCompiling</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_bmethod" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_bmethod</span><span
                                class="method-args">(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_bmethod @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_bmethod-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5275</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_bmethod</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-identifier">proc_addr</span> = <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">bmethod</span>.<span class="ruby-identifier">proc</span>

  <span class="ruby-identifier">proc_t</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_yjit_get_proc_ptr</span>(<span class="ruby-identifier">proc_addr</span>)
  <span class="ruby-identifier">proc_block</span> = <span class="ruby-identifier">proc_t</span>.<span class="ruby-identifier">block</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">proc_block</span>.<span class="ruby-identifier">type</span> <span class="ruby-operator">!=</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">block_type_iseq</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_bmethod_not_iseq</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">capture</span> = <span class="ruby-identifier">proc_block</span>.<span class="ruby-identifier">as</span>.<span class="ruby-identifier">captured</span>
  <span class="ruby-identifier">iseq</span> = <span class="ruby-identifier">capture</span>.<span class="ruby-identifier">code</span>.<span class="ruby-identifier">iseq</span>

  <span class="ruby-comment"># TODO: implement this</span>
  <span class="ruby-comment"># Optimize for single ractor mode and avoid runtime check for</span>
  <span class="ruby-comment"># &quot;defined with an un-shareable Proc in a different Ractor&quot;</span>
  <span class="ruby-comment"># if !assume_single_ractor_mode(jit, ocb)</span>
  <span class="ruby-comment">#     return CantCompile;</span>
  <span class="ruby-comment"># end</span>

  <span class="ruby-comment"># Passing a block to a block needs logic different from passing</span>
  <span class="ruby-comment"># a block to a method and sometimes requires allocation. Bail for now.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span> <span class="ruby-operator">!=</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_BLOCK_HANDLER_NONE</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_bmethod_blockarg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">jit_call_iseq</span>(
    <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">iseq</span>,
    <span class="ruby-value">frame_type:</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_FRAME_MAGIC_BLOCK</span> <span class="ruby-operator">|</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_FRAME_FLAG_BMETHOD</span> <span class="ruby-operator">|</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_FRAME_FLAG_LAMBDA</span>,
    <span class="ruby-value">prev_ep:</span> <span class="ruby-identifier">capture</span>.<span class="ruby-identifier">ep</span>,
  )
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_cfunc" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_cfunc</span><span
                                class="method-args">(jit, ctx, asm, cme, calling, known_recv_class: nil)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_cfunc @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_cfunc-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4956</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_cfunc</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-value">known_recv_class:</span> <span class="ruby-keyword">nil</span>)
  <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>
  <span class="ruby-identifier">flags</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span>

  <span class="ruby-identifier">cfunc</span> = <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">cfunc</span>
  <span class="ruby-identifier">cfunc_argc</span> = <span class="ruby-identifier">cfunc</span>.<span class="ruby-identifier">argc</span>

  <span class="ruby-comment"># If the function expects a Ruby array of arguments</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">&lt;</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">!=</span> <span class="ruby-value">-1</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_cfunc_ruby_array_varg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># We aren&#39;t handling a vararg cfuncs with splat currently.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">==</span> <span class="ruby-value">-1</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_args_splat_cfunc_var_args</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ZSUPER</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># zsuper methods are super calls without any arguments.</span>
    <span class="ruby-comment"># They are also marked as splat, but don&#39;t actually have an array</span>
    <span class="ruby-comment"># they pull arguments from, instead we need to change to call</span>
    <span class="ruby-comment"># a different method with the current stack.</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_args_splat_cfunc_zuper</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>;
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># In order to handle backwards compatibility between ruby 3 and 2</span>
  <span class="ruby-comment"># ruby2_keywords was introduced. It is called only on methods</span>
  <span class="ruby-comment"># with splat and changes they way they handle them.</span>
  <span class="ruby-comment"># We are just going to not compile these.</span>
  <span class="ruby-comment"># https://docs.ruby-lang.org/en/3.2/Module.html#method-i-ruby2_keywords</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">ruby2_keywords</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_args_splat_cfunc_ruby2_keywords</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>;
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">kw_arg</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">kwarg</span>
  <span class="ruby-identifier">kw_arg_num</span> = <span class="ruby-keyword">if</span> <span class="ruby-identifier">kw_arg</span>.<span class="ruby-identifier">nil?</span>
    <span class="ruby-value">0</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">kw_arg</span>.<span class="ruby-identifier">keyword_len</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">kw_arg_num</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_cfunc_splat_with_kw</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">c_method_tracing_currently_enabled?</span>
    <span class="ruby-comment"># Don&#39;t JIT if tracing c_call or c_return</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_cfunc_tracing</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Delegate to codegen for C methods if we have it.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">kw_arg</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> (<span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">==</span> <span class="ruby-value">-1</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">argc</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">cfunc_argc</span>)
    <span class="ruby-identifier">known_cfunc_codegen</span> = <span class="ruby-identifier">lookup_cfunc_codegen</span>(<span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>)
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">known_cfunc_codegen</span>&amp;.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">known_recv_class</span>)
      <span class="ruby-comment"># cfunc codegen generated code. Terminate the block so</span>
      <span class="ruby-comment"># there isn&#39;t multiple calls in the same block.</span>
      <span class="ruby-identifier">jump_to_next_insn</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">EndBlock</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Check for interrupts</span>
  <span class="ruby-identifier">jit_check_ints</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)

  <span class="ruby-comment"># Stack overflow check</span>
  <span class="ruby-comment"># #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)</span>
  <span class="ruby-comment"># REG_CFP &lt;= REG_SP + 4 * SIZEOF_VALUE + sizeof(rb_control_frame_t)</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;stack overflow check&#39;</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-value">4</span> <span class="ruby-operator">+</span> <span class="ruby-value">2</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">size</span>))
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmp</span>(<span class="ruby-constant">CFP</span>, <span class="ruby-value">:rax</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">jbe</span>(<span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>), <span class="ruby-value">:send_stackoverflow</span>))

  <span class="ruby-comment"># Number of args which will be passed through to the callee</span>
  <span class="ruby-comment"># This is adjusted by the kwargs being combined into a hash.</span>
  <span class="ruby-identifier">passed_argc</span> = <span class="ruby-keyword">if</span> <span class="ruby-identifier">kw_arg</span>.<span class="ruby-identifier">nil?</span>
    <span class="ruby-identifier">argc</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">kw_arg_num</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># If the argument count doesn&#39;t match</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">&gt;=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">passed_argc</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_cfunc_argc_mismatch</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Don&#39;t JIT functions that need C stack arguments for now</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">&gt;=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">passed_argc</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span> <span class="ruby-operator">&gt;</span> <span class="ruby-constant">C_ARGS</span>.<span class="ruby-identifier">size</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_cfunc_toomany_args</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">block_arg</span> = <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>

  <span class="ruby-comment"># Guard block_arg_type</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">guard_block_arg</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>) <span class="ruby-operator">==</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_arg</span>
    <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-value">1</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># push_splat_args does stack manipulation so we can no longer side exit</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">assert_equal</span>(<span class="ruby-keyword">true</span>, <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">&gt;=</span> <span class="ruby-value">0</span>)
    <span class="ruby-identifier">required_args</span> = <span class="ruby-identifier">cfunc_argc</span> <span class="ruby-operator">-</span> (<span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>)
    <span class="ruby-comment"># + 1 because we pass self</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">required_args</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span> <span class="ruby-operator">&gt;=</span> <span class="ruby-constant">C_ARGS</span>.<span class="ruby-identifier">size</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_cfunc_toomany_args</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-comment"># We are going to assume that the splat fills</span>
    <span class="ruby-comment"># all the remaining arguments. So the number of args</span>
    <span class="ruby-comment"># should just equal the number of args the cfunc takes.</span>
    <span class="ruby-comment"># In the generated code we test if this is true</span>
    <span class="ruby-comment"># and if not side exit.</span>
    <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">cfunc_argc</span>
    <span class="ruby-identifier">passed_argc</span> = <span class="ruby-identifier">argc</span>
    <span class="ruby-identifier">push_splat_args</span>(<span class="ruby-identifier">required_args</span>, <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># This is a .send call and we need to adjust the stack</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">handle_opt_send_shift_stack</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-value">send_shift:</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Points to the receiver operand on the stack</span>

  <span class="ruby-comment"># Store incremented PC into current control frame in case callee raises.</span>
  <span class="ruby-identifier">jit_save_pc</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">asm</span>)

  <span class="ruby-comment"># Increment the stack pointer by 3 (in the callee)</span>
  <span class="ruby-comment"># sp += 3</span>

  <span class="ruby-identifier">frame_type</span> = <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_FRAME_MAGIC_CFUNC</span> <span class="ruby-operator">|</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_FRAME_FLAG_CFRAME</span> <span class="ruby-operator">|</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_ENV_FLAG_LOCAL</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">kw_arg</span>
    <span class="ruby-identifier">frame_type</span> <span class="ruby-operator">|=</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_FRAME_FLAG_CFRAME_KW</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">jit_push_frame</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">flags</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">frame_type</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span>)

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">kw_arg</span>
    <span class="ruby-comment"># Build a hash from all kwargs passed</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;build_kwhash&#39;</span>)
    <span class="ruby-identifier">imemo_ci</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">ci_addr</span>
    <span class="ruby-comment"># we assume all callinfos with kwargs are on the GC heap</span>
    <span class="ruby-identifier">assert_equal</span>(<span class="ruby-keyword">true</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">imemo_type_p</span>(<span class="ruby-identifier">imemo_ci</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">imemo_callinfo</span>))
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">imemo_ci</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-value">0</span>))
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rjit_build_kwhash</span>)

    <span class="ruby-comment"># Replace the stack location at the start of kwargs with the new hash</span>
    <span class="ruby-identifier">stack_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">passed_argc</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_opnd</span>, <span class="ruby-constant">C_RET</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Copy SP because REG_SP will get overwritten</span>
  <span class="ruby-identifier">sp</span> = <span class="ruby-value">:rax</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-identifier">sp</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-value">0</span>))

  <span class="ruby-comment"># Pop the C function arguments from the stack (in the caller)</span>
  <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-identifier">argc</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)

  <span class="ruby-comment"># Write interpreter SP into CFP.</span>
  <span class="ruby-comment"># Needed in case the callee yields to the block.</span>
  <span class="ruby-identifier">jit_save_sp</span>(<span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)

  <span class="ruby-comment"># Non-variadic method</span>
  <span class="ruby-keyword">case</span> <span class="ruby-identifier">cfunc_argc</span>
  <span class="ruby-keyword">in</span> (<span class="ruby-value">0</span><span class="ruby-operator">..</span>) <span class="ruby-comment"># Non-variadic method</span>
    <span class="ruby-comment"># Copy the arguments from the stack to the C argument registers</span>
    <span class="ruby-comment"># self is the 0th argument and is at index argc from the stack top</span>
    (<span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-identifier">passed_argc</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-identifier">i</span>], [<span class="ruby-identifier">sp</span>, <span class="ruby-operator">-</span>(<span class="ruby-identifier">argc</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">i</span>) <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>])
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">in</span> <span class="ruby-value">-1</span> <span class="ruby-comment"># Variadic method: rb_f_puts(int argc, VALUE *argv, VALUE recv)</span>
    <span class="ruby-comment"># The method gets a pointer to the first argument</span>
    <span class="ruby-comment"># rb_f_puts(int argc, VALUE *argv, VALUE recv)</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">passed_argc</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], [<span class="ruby-identifier">sp</span>, <span class="ruby-operator">-</span><span class="ruby-identifier">argc</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>]) <span class="ruby-comment"># argv</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">2</span>], [<span class="ruby-identifier">sp</span>, <span class="ruby-operator">-</span>(<span class="ruby-identifier">argc</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>) <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>]) <span class="ruby-comment"># recv</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Call the C function</span>
  <span class="ruby-comment"># VALUE ret = (cfunc-&gt;func)(recv, argv[0], argv[1]);</span>
  <span class="ruby-comment"># cfunc comes from compile-time cme-&gt;def, which we assume to be stable.</span>
  <span class="ruby-comment"># Invalidation logic is in yjit_method_lookup_change()</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;call C function&#39;</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">cfunc</span>.<span class="ruby-identifier">func</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-value">:rax</span>) <span class="ruby-comment"># TODO: use rel32 if close enough</span>

  <span class="ruby-comment"># Record code position for TracePoint patching. See full_cfunc_return().</span>
  <span class="ruby-constant">Invariants</span>.<span class="ruby-identifier">record_global_inval_patch</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">full_cfunc_return</span>)

  <span class="ruby-comment"># Push the return value on the Ruby stack</span>
  <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-constant">C_RET</span>)

  <span class="ruby-comment"># Pop the stack frame (ec-&gt;cfp++)</span>
  <span class="ruby-comment"># Instead of recalculating, we can reuse the previous CFP, which is stored in a callee-saved</span>
  <span class="ruby-comment"># register</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">EC</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_execution_context_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:cfp</span>)], <span class="ruby-constant">CFP</span>)

  <span class="ruby-comment"># cfunc calls may corrupt types</span>
  <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">clear_local_types</span>

  <span class="ruby-comment"># Note: the return block of jit_call_iseq has ctx-&gt;sp_offset == 1</span>
  <span class="ruby-comment"># which allows for sharing the same successor.</span>

  <span class="ruby-comment"># Jump (fall through) to the call continuation block</span>
  <span class="ruby-comment"># We do this to end the current block after the call</span>
  <span class="ruby-identifier">assert_equal</span>(<span class="ruby-value">1</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_offset</span>)
  <span class="ruby-identifier">jump_to_next_insn</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-constant">EndBlock</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_general" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_general</span><span
                                class="method-args">(jit, ctx, asm, mid, calling, cme, known_recv_class)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_general @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_general-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4247</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_general</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">mid</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-identifier">jit_call_method</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">mid</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">known_recv_class</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_iseq" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_iseq</span><span
                                class="method-args">(jit, ctx, asm, cme, calling, iseq, frame_type: nil, prev_ep: nil)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_iseq_setup @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_iseq-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4342</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_iseq</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">iseq</span>, <span class="ruby-value">frame_type:</span> <span class="ruby-keyword">nil</span>, <span class="ruby-value">prev_ep:</span> <span class="ruby-keyword">nil</span>)
  <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>
  <span class="ruby-identifier">flags</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span>
  <span class="ruby-identifier">send_shift</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span>

  <span class="ruby-comment"># When you have keyword arguments, there is an extra object that gets</span>
  <span class="ruby-comment"># placed on the stack the represents a bitmap of the keywords that were not</span>
  <span class="ruby-comment"># specified at the call site. We need to keep track of the fact that this</span>
  <span class="ruby-comment"># value is present on the stack in order to properly set up the callee&#39;s</span>
  <span class="ruby-comment"># stack pointer.</span>
  <span class="ruby-identifier">doing_kw_call</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_kw</span>
  <span class="ruby-identifier">supplying_kws</span> = <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KWARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_TAILCALL</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># We can&#39;t handle tailcalls</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_tailcall</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># No support for callees with these parameters yet as they require allocation</span>
  <span class="ruby-comment"># or complex handling.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_post</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_has_opt</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_kwrest</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_has_kwrest</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># In order to handle backwards compatibility between ruby 3 and 2</span>
  <span class="ruby-comment"># ruby2_keywords was introduced. It is called only on methods</span>
  <span class="ruby-comment"># with splat and changes they way they handle them.</span>
  <span class="ruby-comment"># We are just going to not compile these.</span>
  <span class="ruby-comment"># https://www.rubydoc.info/stdlib/core/Proc:ruby2_keywords</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">ruby2_keywords</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_ruby2_keywords</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">iseq_has_rest</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_rest</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq_has_rest</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-value">:captured</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_has_rest_and_captured</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq_has_rest</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_kw</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">supplying_kws</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_has_rest_and_kw_supplied</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># If we have keyword arguments being passed to a callee that only takes</span>
  <span class="ruby-comment"># positionals, then we need to allocate a hash. For now we&#39;re going to</span>
  <span class="ruby-comment"># call that too complex and bail.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">supplying_kws</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_kw</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_has_no_kw</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># If we have a method accepting no kwargs (**nil), exit if we have passed</span>
  <span class="ruby-comment"># it any kwargs.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">supplying_kws</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">accepts_no_kwarg</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_accepts_no_kwarg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># For computing number of locals to set up for the callee</span>
  <span class="ruby-identifier">num_params</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">size</span>

  <span class="ruby-comment"># Block parameter handling. This mirrors setup_parameters_complex().</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_block</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">local_iseq</span>.<span class="ruby-identifier">to_i</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">to_i</span>
      <span class="ruby-identifier">num_params</span> <span class="ruby-operator">-=</span> <span class="ruby-value">1</span>
    <span class="ruby-keyword">else</span>
      <span class="ruby-comment"># In this case (param.flags.has_block &amp;&amp; local_iseq != iseq),</span>
      <span class="ruby-comment"># the block argument is setup as a local variable and requires</span>
      <span class="ruby-comment"># materialization (allocation). Bail.</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_materialized_block</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ZSUPER</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># zsuper methods are super calls without any arguments.</span>
    <span class="ruby-comment"># They are also marked as splat, but don&#39;t actually have an array</span>
    <span class="ruby-comment"># they pull arguments from, instead we need to change to call</span>
    <span class="ruby-comment"># a different method with the current stack.</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_zsuper</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">start_pc_offset</span> = <span class="ruby-value">0</span>
  <span class="ruby-identifier">required_num</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">lead_num</span>

  <span class="ruby-comment"># This struct represents the metadata about the caller-specified</span>
  <span class="ruby-comment"># keyword arguments.</span>
  <span class="ruby-identifier">kw_arg</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">kwarg</span>
  <span class="ruby-identifier">kw_arg_num</span> = <span class="ruby-keyword">if</span> <span class="ruby-identifier">kw_arg</span>.<span class="ruby-identifier">nil?</span>
    <span class="ruby-value">0</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">kw_arg</span>.<span class="ruby-identifier">keyword_len</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Arity handling and optional parameter setup</span>
  <span class="ruby-identifier">opts_filled</span> = <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">required_num</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">kw_arg_num</span>
  <span class="ruby-identifier">opt_num</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">opt_num</span>
  <span class="ruby-identifier">opts_missing</span> = <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">opts_filled</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">doing_kw_call</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_splat_with_kw</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq_has_rest</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_has_rest_and_optional</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">opts_filled</span> <span class="ruby-operator">&lt;</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># Too few arguments and no splat to make up for it</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_arity_error</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">opts_filled</span> <span class="ruby-operator">&gt;</span> <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">iseq_has_rest</span>
    <span class="ruby-comment"># Too many arguments and no place to put them (i.e. rest arg)</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_arity_error</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">block_arg</span> = <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>

  <span class="ruby-comment"># Guard block_arg_type</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">guard_block_arg</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>) <span class="ruby-operator">==</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># If we have unfilled optional arguments and keyword arguments then we</span>
  <span class="ruby-comment"># would need to adjust the arguments location to account for that.</span>
  <span class="ruby-comment"># For now we aren&#39;t handling this case.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">doing_kw_call</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">opts_missing</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_missing_optional_kw</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># We will handle splat case later</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">num_params</span> <span class="ruby-operator">-=</span> <span class="ruby-identifier">opts_missing</span>
    <span class="ruby-identifier">start_pc_offset</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">opt_table</span>[<span class="ruby-identifier">opts_filled</span>]
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">doing_kw_call</span>
    <span class="ruby-comment"># Here we&#39;re calling a method with keyword arguments and specifying</span>
    <span class="ruby-comment"># keyword arguments at this call site.</span>

    <span class="ruby-comment"># This struct represents the metadata about the callee-specified</span>
    <span class="ruby-comment"># keyword parameters.</span>
    <span class="ruby-identifier">keyword</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">keyword</span>
    <span class="ruby-identifier">keyword_num</span> = <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">num</span>
    <span class="ruby-identifier">keyword_required_num</span> = <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">required_num</span>

    <span class="ruby-identifier">required_kwargs_filled</span> = <span class="ruby-value">0</span>

    <span class="ruby-keyword">if</span> <span class="ruby-identifier">keyword_num</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">30</span>
      <span class="ruby-comment"># We have so many keywords that (1 &lt;&lt; num) encoded as a FIXNUM</span>
      <span class="ruby-comment"># (which shifts it left one more) no longer fits inside a 32-bit</span>
      <span class="ruby-comment"># immediate.</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_too_many_kwargs</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-comment"># Check that the kwargs being passed are valid</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">supplying_kws</span>
      <span class="ruby-comment"># This is the list of keyword arguments that the callee specified</span>
      <span class="ruby-comment"># in its initial declaration.</span>
      <span class="ruby-comment"># SAFETY: see compile.c for sizing of this slice.</span>
      <span class="ruby-identifier">callee_kwargs</span> = <span class="ruby-identifier">keyword_num</span>.<span class="ruby-identifier">times</span>.<span class="ruby-identifier">map</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span> <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">table</span>[<span class="ruby-identifier">i</span>] }

      <span class="ruby-comment"># Here we&#39;re going to build up a list of the IDs that correspond to</span>
      <span class="ruby-comment"># the caller-specified keyword arguments. If they&#39;re not in the</span>
      <span class="ruby-comment"># same order as the order specified in the callee declaration, then</span>
      <span class="ruby-comment"># we&#39;re going to need to generate some code to swap values around</span>
      <span class="ruby-comment"># on the stack.</span>
      <span class="ruby-identifier">caller_kwargs</span> = []
      <span class="ruby-identifier">kw_arg</span>.<span class="ruby-identifier">keyword_len</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">kwarg_idx</span><span class="ruby-operator">|</span>
        <span class="ruby-identifier">sym</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">to_ruby</span>(<span class="ruby-identifier">kw_arg</span>[<span class="ruby-value">:keywords</span>][<span class="ruby-identifier">kwarg_idx</span>])
        <span class="ruby-identifier">caller_kwargs</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_sym2id</span>(<span class="ruby-identifier">sym</span>)
      <span class="ruby-keyword">end</span>

      <span class="ruby-comment"># First, we&#39;re going to be sure that the names of every</span>
      <span class="ruby-comment"># caller-specified keyword argument correspond to a name in the</span>
      <span class="ruby-comment"># list of callee-specified keyword parameters.</span>
      <span class="ruby-identifier">caller_kwargs</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">caller_kwarg</span><span class="ruby-operator">|</span>
        <span class="ruby-identifier">search_result</span> = <span class="ruby-identifier">callee_kwargs</span>.<span class="ruby-identifier">map</span>.<span class="ruby-identifier">with_index</span>.<span class="ruby-identifier">find</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">kwarg</span>, <span class="ruby-identifier">_</span><span class="ruby-operator">|</span> <span class="ruby-identifier">kwarg</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">caller_kwarg</span> }

        <span class="ruby-keyword">case</span> <span class="ruby-identifier">search_result</span>
        <span class="ruby-keyword">in</span> <span class="ruby-keyword">nil</span>
          <span class="ruby-comment"># If the keyword was never found, then we know we have a</span>
          <span class="ruby-comment"># mismatch in the names of the keyword arguments, so we need to</span>
          <span class="ruby-comment"># bail.</span>
          <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_kwargs_mismatch</span>)
          <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
        <span class="ruby-keyword">in</span> <span class="ruby-identifier">_</span>, <span class="ruby-identifier">callee_idx</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">callee_idx</span> <span class="ruby-operator">&lt;</span> <span class="ruby-identifier">keyword_required_num</span>
          <span class="ruby-comment"># Keep a count to ensure all required kwargs are specified</span>
          <span class="ruby-identifier">required_kwargs_filled</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
        <span class="ruby-keyword">else</span>
        <span class="ruby-keyword">end</span>
      <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-identifier">assert_equal</span>(<span class="ruby-keyword">true</span>, <span class="ruby-identifier">required_kwargs_filled</span> <span class="ruby-operator">&lt;=</span> <span class="ruby-identifier">keyword_required_num</span>)
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">required_kwargs_filled</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">keyword_required_num</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_kwargs_mismatch</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Check if we need the arg0 splat handling of vm_callee_setup_block_arg</span>
  <span class="ruby-identifier">arg_setup_block</span> = (<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-value">:captured</span>) <span class="ruby-comment"># arg_setup_type: arg_setup_block (invokeblock)</span>
  <span class="ruby-identifier">block_arg0_splat</span> = <span class="ruby-identifier">arg_setup_block</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">argc</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span> <span class="ruby-operator">&amp;&amp;</span>
    (<span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">has_lead</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">1</span>) <span class="ruby-operator">&amp;&amp;</span>
    <span class="ruby-operator">!</span><span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">flags</span>.<span class="ruby-identifier">ambiguous_param0</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_arg0_splat</span>
    <span class="ruby-comment"># If block_arg0_splat, we still need side exits after splat, but</span>
    <span class="ruby-comment"># doing push_splat_args here disallows it. So bail out.</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">iseq_has_rest</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:invokeblock_iseq_arg0_args_splat</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-comment"># The block_arg0_splat implementation is for the rb_simple_iseq_p case,</span>
    <span class="ruby-comment"># but doing_kw_call means it&#39;s not a simple ISEQ.</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">doing_kw_call</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:invokeblock_iseq_arg0_has_kw</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-comment"># The block_arg0_splat implementation cannot deal with optional parameters.</span>
    <span class="ruby-comment"># This is a setup_parameters_complex() situation and interacts with the</span>
    <span class="ruby-comment"># starting position of the callee.</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">1</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:invokeblock_iseq_arg0_optional</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">iseq_has_rest</span>
    <span class="ruby-identifier">array</span> = <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">peek_at_stack</span>(<span class="ruby-identifier">block_arg</span> <span class="ruby-operator">?</span> <span class="ruby-value">1</span> <span class="ruby-operator">:</span> <span class="ruby-value">0</span>)
    <span class="ruby-identifier">splat_array_length</span> = <span class="ruby-keyword">if</span> <span class="ruby-identifier">array</span>.<span class="ruby-identifier">nil?</span>
      <span class="ruby-value">0</span>
    <span class="ruby-keyword">else</span>
      <span class="ruby-identifier">array</span>.<span class="ruby-identifier">length</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-keyword">if</span> <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">required_num</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">splat_array_length</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_splat_arity_error</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># We will not have CantCompile from here.</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_arg</span>
    <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-value">1</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_BLOCK_HANDLER_NONE</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">builtin_attrs</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">BUILTIN_ATTR_LEAF</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">jit_leaf_builtin_func</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">flags</span>, <span class="ruby-identifier">iseq</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">KeepCompiling</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Number of locals that are not parameters</span>
  <span class="ruby-identifier">num_locals</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">local_table_size</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">num_params</span>

  <span class="ruby-comment"># Stack overflow check</span>
  <span class="ruby-comment"># Note that vm_push_frame checks it against a decremented cfp, hence the multiply by 2.</span>
  <span class="ruby-comment"># #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;stack overflow check&#39;</span>)
  <span class="ruby-identifier">locals_offs</span> = <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">num_locals</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">stack_max</span>) <span class="ruby-operator">+</span> <span class="ruby-value">2</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">size</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-identifier">locals_offs</span>))
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmp</span>(<span class="ruby-constant">CFP</span>, <span class="ruby-value">:rax</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">jbe</span>(<span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>), <span class="ruby-value">:send_stackoverflow</span>))

  <span class="ruby-comment"># push_splat_args does stack manipulation so we can no longer side exit</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">splat_array_length</span>
    <span class="ruby-identifier">remaining_opt</span> = (<span class="ruby-identifier">opt_num</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">required_num</span>) <span class="ruby-operator">-</span> (<span class="ruby-identifier">splat_array_length</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>))

    <span class="ruby-keyword">if</span> <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">0</span>
      <span class="ruby-comment"># We are going to jump to the correct offset based on how many optional</span>
      <span class="ruby-comment"># params are remaining.</span>
      <span class="ruby-identifier">offset</span> = <span class="ruby-identifier">opt_num</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">remaining_opt</span>
      <span class="ruby-identifier">start_pc_offset</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">opt_table</span>[<span class="ruby-identifier">offset</span>]
    <span class="ruby-keyword">end</span>
    <span class="ruby-comment"># We are going to assume that the splat fills</span>
    <span class="ruby-comment"># all the remaining arguments. In the generated code</span>
    <span class="ruby-comment"># we test if this is true and if not side exit.</span>
    <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">splat_array_length</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">remaining_opt</span>
    <span class="ruby-identifier">push_splat_args</span>(<span class="ruby-identifier">splat_array_length</span>, <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)

    <span class="ruby-identifier">remaining_opt</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span>
      <span class="ruby-comment"># We need to push nil for the optional arguments</span>
      <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-constant">Qnil</span>)
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># This is a .send call and we need to adjust the stack</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">handle_opt_send_shift_stack</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-value">send_shift:</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq_has_rest</span>
    <span class="ruby-comment"># We are going to allocate so setting pc and sp.</span>
    <span class="ruby-identifier">jit_save_pc</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">asm</span>) <span class="ruby-comment"># clobbers rax</span>
    <span class="ruby-identifier">jit_save_sp</span>(<span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)

    <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
      <span class="ruby-identifier">non_rest_arg_count</span> = <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>
      <span class="ruby-comment"># We start by dupping the array because someone else might have</span>
      <span class="ruby-comment"># a reference to it.</span>
      <span class="ruby-identifier">array</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-value">1</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">array</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_ary_dup</span>)
      <span class="ruby-identifier">array</span> = <span class="ruby-constant">C_RET</span>
      <span class="ruby-keyword">if</span> <span class="ruby-identifier">non_rest_arg_count</span> <span class="ruby-operator">&gt;</span> <span class="ruby-identifier">required_num</span>
        <span class="ruby-comment"># If we have more arguments than required, we need to prepend</span>
        <span class="ruby-comment"># the items from the stack onto the array.</span>
        <span class="ruby-identifier">diff</span> = (<span class="ruby-identifier">non_rest_arg_count</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">required_num</span>)

        <span class="ruby-comment"># diff is &gt;0 so no need to worry about null pointer</span>
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;load pointer to array elements&#39;</span>)
        <span class="ruby-identifier">offset_magnitude</span> = <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">diff</span>
        <span class="ruby-identifier">values_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-operator">-</span><span class="ruby-identifier">offset_magnitude</span>)
        <span class="ruby-identifier">values_ptr</span> = <span class="ruby-value">:rcx</span>
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-identifier">values_ptr</span>, <span class="ruby-identifier">values_opnd</span>)

        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;prepend stack values to rest array&#39;</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">diff</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">values_ptr</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">2</span>], <span class="ruby-identifier">array</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_ary_unshift_m</span>)
        <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-identifier">diff</span>)

        <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">TArray</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-constant">C_RET</span>)
        <span class="ruby-comment"># We now should have the required arguments</span>
        <span class="ruby-comment"># and an array of all the rest arguments</span>
        <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">required_num</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
      <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">non_rest_arg_count</span> <span class="ruby-operator">&lt;</span> <span class="ruby-identifier">required_num</span>
        <span class="ruby-comment"># If we have fewer arguments than required, we need to take some</span>
        <span class="ruby-comment"># from the array and move them to the stack.</span>
        <span class="ruby-identifier">diff</span> = (<span class="ruby-identifier">required_num</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">non_rest_arg_count</span>)
        <span class="ruby-comment"># This moves the arguments onto the stack. But it doesn&#39;t modify the array.</span>
        <span class="ruby-identifier">move_rest_args_to_stack</span>(<span class="ruby-identifier">array</span>, <span class="ruby-identifier">diff</span>, <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)

        <span class="ruby-comment"># We will now slice the array to give us a new array of the correct size</span>
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">array</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">diff</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rjit_rb_ary_subseq_length</span>)
        <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">TArray</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-constant">C_RET</span>)

        <span class="ruby-comment"># We now should have the required arguments</span>
        <span class="ruby-comment"># and an array of all the rest arguments</span>
        <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">required_num</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
      <span class="ruby-keyword">else</span>
        <span class="ruby-comment"># The arguments are equal so we can just push to the stack</span>
        <span class="ruby-identifier">assert_equal</span>(<span class="ruby-identifier">non_rest_arg_count</span>, <span class="ruby-identifier">required_num</span>)
        <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">TArray</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-identifier">array</span>)
      <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">else</span>
      <span class="ruby-identifier">assert_equal</span>(<span class="ruby-keyword">true</span>, <span class="ruby-identifier">argc</span> <span class="ruby-operator">&gt;=</span> <span class="ruby-identifier">required_num</span>)
      <span class="ruby-identifier">n</span> = (<span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">required_num</span>)
      <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">required_num</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
      <span class="ruby-comment"># If n is 0, then elts is never going to be read, so we can just pass null</span>
      <span class="ruby-keyword">if</span> <span class="ruby-identifier">n</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
        <span class="ruby-identifier">values_ptr</span> = <span class="ruby-value">0</span>
      <span class="ruby-keyword">else</span>
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;load pointer to array elements&#39;</span>)
        <span class="ruby-identifier">offset_magnitude</span> = <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">n</span>
        <span class="ruby-identifier">values_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-operator">-</span><span class="ruby-identifier">offset_magnitude</span>)
        <span class="ruby-identifier">values_ptr</span> = <span class="ruby-value">:rcx</span>
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-identifier">values_ptr</span>, <span class="ruby-identifier">values_opnd</span>)
      <span class="ruby-keyword">end</span>

      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-constant">EC</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">n</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">2</span>], <span class="ruby-identifier">values_ptr</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_ec_ary_new_from_values</span>)

      <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-identifier">n</span>)
      <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">TArray</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-constant">C_RET</span>)
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">doing_kw_call</span>
    <span class="ruby-comment"># Here we&#39;re calling a method with keyword arguments and specifying</span>
    <span class="ruby-comment"># keyword arguments at this call site.</span>

    <span class="ruby-comment"># Number of positional arguments the callee expects before the first</span>
    <span class="ruby-comment"># keyword argument</span>
    <span class="ruby-identifier">args_before_kw</span> = <span class="ruby-identifier">required_num</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">opt_num</span>

    <span class="ruby-comment"># This struct represents the metadata about the caller-specified</span>
    <span class="ruby-comment"># keyword arguments.</span>
    <span class="ruby-identifier">ci_kwarg</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">kwarg</span>
    <span class="ruby-identifier">caller_keyword_len</span> = <span class="ruby-keyword">if</span> <span class="ruby-identifier">ci_kwarg</span>.<span class="ruby-identifier">nil?</span>
      <span class="ruby-value">0</span>
    <span class="ruby-keyword">else</span>
      <span class="ruby-identifier">ci_kwarg</span>.<span class="ruby-identifier">keyword_len</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-comment"># This struct represents the metadata about the callee-specified</span>
    <span class="ruby-comment"># keyword parameters.</span>
    <span class="ruby-identifier">keyword</span> = <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">param</span>.<span class="ruby-identifier">keyword</span>

    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;keyword args&#39;</span>)

    <span class="ruby-comment"># This is the list of keyword arguments that the callee specified</span>
    <span class="ruby-comment"># in its initial declaration.</span>
    <span class="ruby-identifier">callee_kwargs</span> = <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">table</span>
    <span class="ruby-identifier">total_kwargs</span> = <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">num</span>

    <span class="ruby-comment"># Here we&#39;re going to build up a list of the IDs that correspond to</span>
    <span class="ruby-comment"># the caller-specified keyword arguments. If they&#39;re not in the</span>
    <span class="ruby-comment"># same order as the order specified in the callee declaration, then</span>
    <span class="ruby-comment"># we&#39;re going to need to generate some code to swap values around</span>
    <span class="ruby-comment"># on the stack.</span>
    <span class="ruby-identifier">caller_kwargs</span> = []

    <span class="ruby-identifier">caller_keyword_len</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">kwarg_idx</span><span class="ruby-operator">|</span>
      <span class="ruby-identifier">sym</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">to_ruby</span>(<span class="ruby-identifier">ci_kwarg</span>[<span class="ruby-value">:keywords</span>][<span class="ruby-identifier">kwarg_idx</span>])
      <span class="ruby-identifier">caller_kwargs</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_sym2id</span>(<span class="ruby-identifier">sym</span>)
    <span class="ruby-keyword">end</span>
    <span class="ruby-identifier">kwarg_idx</span> = <span class="ruby-identifier">caller_keyword_len</span>

    <span class="ruby-identifier">unspecified_bits</span> = <span class="ruby-value">0</span>

    <span class="ruby-identifier">keyword_required_num</span> = <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">required_num</span>
    (<span class="ruby-identifier">keyword_required_num</span><span class="ruby-operator">...</span><span class="ruby-identifier">total_kwargs</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">callee_idx</span><span class="ruby-operator">|</span>
      <span class="ruby-identifier">already_passed</span> = <span class="ruby-keyword">false</span>
      <span class="ruby-identifier">callee_kwarg</span> = <span class="ruby-identifier">callee_kwargs</span>[<span class="ruby-identifier">callee_idx</span>]

      <span class="ruby-identifier">caller_keyword_len</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">caller_idx</span><span class="ruby-operator">|</span>
        <span class="ruby-keyword">if</span> <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">caller_idx</span>] <span class="ruby-operator">==</span> <span class="ruby-identifier">callee_kwarg</span>
          <span class="ruby-identifier">already_passed</span> = <span class="ruby-keyword">true</span>
          <span class="ruby-keyword">break</span>
        <span class="ruby-keyword">end</span>
      <span class="ruby-keyword">end</span>

      <span class="ruby-keyword">unless</span> <span class="ruby-identifier">already_passed</span>
        <span class="ruby-comment"># Reserve space on the stack for each default value we&#39;ll be</span>
        <span class="ruby-comment"># filling in (which is done in the next loop). Also increments</span>
        <span class="ruby-comment"># argc so that the callee&#39;s SP is recorded correctly.</span>
        <span class="ruby-identifier">argc</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
        <span class="ruby-identifier">default_arg</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)

        <span class="ruby-comment"># callee_idx - keyword-&gt;required_num is used in a couple of places below.</span>
        <span class="ruby-identifier">req_num</span> = <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">required_num</span>
        <span class="ruby-identifier">extra_args</span> = <span class="ruby-identifier">callee_idx</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">req_num</span>

        <span class="ruby-comment"># VALUE default_value = keyword-&gt;default_values[callee_idx - keyword-&gt;required_num];</span>
        <span class="ruby-identifier">default_value</span> = <span class="ruby-identifier">keyword</span>.<span class="ruby-identifier">default_values</span>[<span class="ruby-identifier">extra_args</span>]

        <span class="ruby-keyword">if</span> <span class="ruby-identifier">default_value</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Qundef</span>
          <span class="ruby-comment"># Qundef means that this value is not constant and must be</span>
          <span class="ruby-comment"># recalculated at runtime, so we record it in unspecified_bits</span>
          <span class="ruby-comment"># (Qnil is then used as a placeholder instead of Qundef).</span>
          <span class="ruby-identifier">unspecified_bits</span> <span class="ruby-operator">|=</span> <span class="ruby-value">0x01</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">extra_args</span>
          <span class="ruby-identifier">default_value</span> = <span class="ruby-constant">Qnil</span>
        <span class="ruby-keyword">end</span>

        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">default_value</span>)
        <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">default_arg</span>, <span class="ruby-value">:rax</span>)

        <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">kwarg_idx</span>] = <span class="ruby-identifier">callee_kwarg</span>
        <span class="ruby-identifier">kwarg_idx</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
      <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-identifier">assert_equal</span>(<span class="ruby-identifier">kwarg_idx</span>, <span class="ruby-identifier">total_kwargs</span>)

    <span class="ruby-comment"># Next, we&#39;re going to loop through every keyword that was</span>
    <span class="ruby-comment"># specified by the caller and make sure that it&#39;s in the correct</span>
    <span class="ruby-comment"># place. If it&#39;s not we&#39;re going to swap it around with another one.</span>
    <span class="ruby-identifier">total_kwargs</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">kwarg_idx</span><span class="ruby-operator">|</span>
      <span class="ruby-identifier">callee_kwarg</span> = <span class="ruby-identifier">callee_kwargs</span>[<span class="ruby-identifier">kwarg_idx</span>]

      <span class="ruby-comment"># If the argument is already in the right order, then we don&#39;t</span>
      <span class="ruby-comment"># need to generate any code since the expected value is already</span>
      <span class="ruby-comment"># in the right place on the stack.</span>
      <span class="ruby-keyword">if</span> <span class="ruby-identifier">callee_kwarg</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">kwarg_idx</span>]
        <span class="ruby-keyword">next</span>
      <span class="ruby-keyword">end</span>

      <span class="ruby-comment"># In this case the argument is not in the right place, so we</span>
      <span class="ruby-comment"># need to find its position where it _should_ be and swap with</span>
      <span class="ruby-comment"># that location.</span>
      ((<span class="ruby-identifier">kwarg_idx</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)<span class="ruby-operator">...</span><span class="ruby-identifier">total_kwargs</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">swap_idx</span><span class="ruby-operator">|</span>
        <span class="ruby-keyword">if</span> <span class="ruby-identifier">callee_kwarg</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">swap_idx</span>]
          <span class="ruby-comment"># First we&#39;re going to generate the code that is going</span>
          <span class="ruby-comment"># to perform the actual swapping at runtime.</span>
          <span class="ruby-identifier">offset0</span> = <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">swap_idx</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">args_before_kw</span>
          <span class="ruby-identifier">offset1</span> = <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">kwarg_idx</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">args_before_kw</span>
          <span class="ruby-identifier">stack_swap</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">offset0</span>, <span class="ruby-identifier">offset1</span>)

          <span class="ruby-comment"># Next we&#39;re going to do some bookkeeping on our end so</span>
          <span class="ruby-comment"># that we know the order that the arguments are</span>
          <span class="ruby-comment"># actually in now.</span>
          <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">kwarg_idx</span>], <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">swap_idx</span>] =
            <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">swap_idx</span>], <span class="ruby-identifier">caller_kwargs</span>[<span class="ruby-identifier">kwarg_idx</span>]

          <span class="ruby-keyword">break</span>
        <span class="ruby-keyword">end</span>
      <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-comment"># Keyword arguments cause a special extra local variable to be</span>
    <span class="ruby-comment"># pushed onto the stack that represents the parameters that weren&#39;t</span>
    <span class="ruby-comment"># explicitly given a value and have a non-constant default.</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-value">-1</span>), <span class="ruby-constant">C</span>.<span class="ruby-identifier">to_value</span>(<span class="ruby-identifier">unspecified_bits</span>))
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Same as vm_callee_setup_block_arg_arg0_check and vm_callee_setup_block_arg_arg0_splat</span>
  <span class="ruby-comment"># on vm_callee_setup_block_arg for arg_setup_block. This is done after CALLER_SETUP_ARG</span>
  <span class="ruby-comment"># and CALLER_REMOVE_EMPTY_KW_SPLAT, so this implementation is put here. This may need</span>
  <span class="ruby-comment"># side exits, so you still need to allow side exits here if block_arg0_splat is true.</span>
  <span class="ruby-comment"># Note that you can&#39;t have side exits after this arg0 splat.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_arg0_splat</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_iseq_block_arg0_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Create a context for the callee</span>
  <span class="ruby-identifier">callee_ctx</span> = <span class="ruby-constant">Context</span>.<span class="ruby-identifier">new</span>

  <span class="ruby-comment"># Set the argument types in the callee&#39;s context</span>
  <span class="ruby-identifier">argc</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">arg_idx</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">stack_offs</span> = <span class="ruby-identifier">argc</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">arg_idx</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>
    <span class="ruby-identifier">arg_type</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">get_opnd_type</span>(<span class="ruby-constant">StackOpnd</span>[<span class="ruby-identifier">stack_offs</span>])
    <span class="ruby-identifier">callee_ctx</span>.<span class="ruby-identifier">set_local_type</span>(<span class="ruby-identifier">arg_idx</span>, <span class="ruby-identifier">arg_type</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">recv_type</span> = <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-value">:captured</span>
    <span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span> <span class="ruby-comment"># we don&#39;t track the type information of captured-&gt;self for now</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">get_opnd_type</span>(<span class="ruby-constant">StackOpnd</span>[<span class="ruby-identifier">argc</span>])
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">callee_ctx</span>.<span class="ruby-identifier">upgrade_opnd_type</span>(<span class="ruby-constant">SelfOpnd</span>, <span class="ruby-identifier">recv_type</span>)

  <span class="ruby-comment"># Setup the new frame</span>
  <span class="ruby-identifier">frame_type</span> <span class="ruby-operator">||=</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_FRAME_MAGIC_METHOD</span> <span class="ruby-operator">|</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_ENV_FLAG_LOCAL</span>
  <span class="ruby-identifier">jit_push_frame</span>(
    <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">flags</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">frame_type</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span>,
    <span class="ruby-value">iseq:</span>       <span class="ruby-identifier">iseq</span>,
    <span class="ruby-value">local_size:</span> <span class="ruby-identifier">num_locals</span>,
    <span class="ruby-value">stack_max:</span>  <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">stack_max</span>,
    <span class="ruby-value">prev_ep:</span>,
    <span class="ruby-value">doing_kw_call:</span>,
  )

  <span class="ruby-comment"># Directly jump to the entry point of the callee</span>
  <span class="ruby-identifier">pc</span> = (<span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">iseq_encoded</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">start_pc_offset</span>).<span class="ruby-identifier">to_i</span>
  <span class="ruby-identifier">jit_direct_jump</span>(<span class="ruby-identifier">iseq</span>, <span class="ruby-identifier">pc</span>, <span class="ruby-identifier">callee_ctx</span>, <span class="ruby-identifier">asm</span>)

  <span class="ruby-constant">EndBlock</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_ivar" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_ivar</span><span
                                class="method-args">(jit, ctx, asm, cme, calling, comptime_recv, recv_opnd)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_ivar (+ part of vm_call_method_each_type) @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_ivar-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5240</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_ivar</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>)
  <span class="ruby-identifier">argc</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>
  <span class="ruby-identifier">flags</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_ivar_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">argc</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_arity</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># We don&#39;t support handle_opt_send_shift_stack for this yet.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_ivar_opt_send</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">ivar_id</span> = <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">attr</span>.<span class="ruby-identifier">id</span>

  <span class="ruby-comment"># Not handling block_handler</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_block_arg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">jit_getivar</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">ivar_id</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-constant">StackOpnd</span>[<span class="ruby-value">0</span>])
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_method" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_method</span><span
                                class="method-args">(jit, ctx, asm, mid, calling, cme, known_recv_class)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_method @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler] @param send_shift [Integer] The number of shifts needed for VM_CALL_OPT_SEND</p>

                              <div class="method-source-code" id="jit_call_method-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4256</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_method</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">mid</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-comment"># The main check of vm_call_method before vm_call_method_each_type</span>
  <span class="ruby-keyword">case</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">METHOD_ENTRY_VISI</span>(<span class="ruby-identifier">cme</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">METHOD_VISI_PUBLIC</span>
    <span class="ruby-comment"># You can always call public methods</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">METHOD_VISI_PRIVATE</span>
    <span class="ruby-comment"># Allow only callsites without a receiver</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_FCALL</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_private</span>)
      <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">METHOD_VISI_PROTECTED</span>
    <span class="ruby-comment"># If the method call is an FCALL, it is always valid</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_FCALL</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
      <span class="ruby-comment"># otherwise we need an ancestry check to ensure the receiver is valid to be called as protected</span>
      <span class="ruby-identifier">jit_protected_callee_ancestry_guard</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>))
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Get a compile-time receiver</span>
  <span class="ruby-identifier">recv_idx</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">?</span> <span class="ruby-value">1</span> <span class="ruby-operator">:</span> <span class="ruby-value">0</span>) <span class="ruby-comment"># blockarg is not popped yet</span>
  <span class="ruby-identifier">recv_idx</span> <span class="ruby-operator">+=</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span>
  <span class="ruby-identifier">comptime_recv</span> = <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">peek_at_stack</span>(<span class="ruby-identifier">recv_idx</span>)
  <span class="ruby-identifier">recv_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">recv_idx</span>)

  <span class="ruby-identifier">jit_call_method_each_type</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-identifier">known_recv_class</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_method_each_type" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_method_each_type</span><span
                                class="method-args">(jit, ctx, asm, calling, cme, comptime_recv, recv_opnd, known_recv_class)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_method_each_type @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_method_each_type-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4303</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_method_each_type</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">case</span> <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>.<span class="ruby-identifier">type</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_ISEQ</span>
    <span class="ruby-identifier">iseq</span> = <span class="ruby-identifier">def_iseq_ptr</span>(<span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>)
    <span class="ruby-identifier">jit_call_iseq</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">iseq</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_NOTIMPLEMENTED</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_notimplemented</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_CFUNC</span>
    <span class="ruby-identifier">jit_call_cfunc</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-value">known_recv_class:</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_ATTRSET</span>
    <span class="ruby-identifier">jit_call_attrset</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_IVAR</span>
    <span class="ruby-identifier">jit_call_ivar</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_MISSING</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_missing</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_BMETHOD</span>
    <span class="ruby-identifier">jit_call_bmethod</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_ALIAS</span>
    <span class="ruby-identifier">jit_call_alias</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_OPTIMIZED</span>
    <span class="ruby-identifier">jit_call_optimized</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_UNDEF</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_undef</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_ZSUPER</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_zsuper</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_METHOD_TYPE_REFINED</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_refined</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_opt_call" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_opt_call</span><span
                                class="method-args">(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_opt_call @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_opt_call-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5376</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_opt_call</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">flags</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">block_handler</span>, <span class="ruby-identifier">known_recv_class</span>, <span class="ruby-value">send_shift:</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_handler</span> <span class="ruby-operator">!=</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_BLOCK_HANDLER_NONE</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_call_block</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KWARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_call_kwarg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_call_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># TODO: implement this</span>
  <span class="ruby-comment"># Optimize for single ractor mode and avoid runtime check for</span>
  <span class="ruby-comment"># &quot;defined with an un-shareable Proc in a different Ractor&quot;</span>
  <span class="ruby-comment"># if !assume_single_ractor_mode(jit, ocb)</span>
  <span class="ruby-comment">#   return CantCompile</span>
  <span class="ruby-comment"># end</span>

  <span class="ruby-comment"># If this is a .send call we need to adjust the stack</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">handle_opt_send_shift_stack</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-value">send_shift:</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># About to reset the SP, need to load this here</span>
  <span class="ruby-identifier">recv_idx</span> = <span class="ruby-identifier">argc</span> <span class="ruby-comment"># blockarg is not supported. send_shift is already handled.</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rcx</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">recv_idx</span>)) <span class="ruby-comment"># recv</span>

  <span class="ruby-comment"># Save the PC and SP because the callee can make Ruby calls</span>
  <span class="ruby-identifier">jit_prepare_routine_call</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>) <span class="ruby-comment"># NOTE: clobbers rax</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-value">0</span>)) <span class="ruby-comment"># sp</span>

  <span class="ruby-identifier">kw_splat</span> = <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KW_SPLAT</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-value">:rcx</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-constant">EC</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">2</span>], <span class="ruby-identifier">argc</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">3</span>], [<span class="ruby-value">:rax</span>, <span class="ruby-operator">-</span><span class="ruby-identifier">argc</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>]) <span class="ruby-comment"># stack_argument_pointer. NOTE: C_ARGS[3] is rcx</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">4</span>], <span class="ruby-identifier">kw_splat</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">5</span>], <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_BLOCK_HANDLER_NONE</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rjit_optimized_call</span>)

  <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-identifier">argc</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)

  <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-constant">C_RET</span>)
  <span class="ruby-keyword">return</span> <span class="ruby-constant">KeepCompiling</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_opt_send" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_opt_send</span><span
                                class="method-args">(jit, ctx, asm, cme, calling, known_recv_class)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_opt_send @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_opt_send-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5350</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_opt_send</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">jit_caller_setup_arg</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span>) <span class="ruby-operator">==</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_send_no_args</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span> <span class="ruby-operator">-=</span> <span class="ruby-value">1</span>
  <span class="ruby-comment"># We aren&#39;t handling `send(:send, ...)` yet. This might work, but not tested yet.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_send_send</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-comment"># Lazily handle stack shift in handle_opt_send_shift_stack</span>
  <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>

  <span class="ruby-identifier">jit_call_symbol</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">known_recv_class</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_FCALL</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_opt_struct_aref" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_opt_struct_aref</span><span
                                class="method-args">(jit, ctx, asm, cme, flags, argc, block_handler, known_recv_class, send_shift:)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_opt_struct_aref @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_opt_struct_aref-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5434</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_opt_struct_aref</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">flags</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">block_handler</span>, <span class="ruby-identifier">known_recv_class</span>, <span class="ruby-value">send_shift:</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">argc</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_struct_aref_error</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">off</span> = <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">optimized</span>.<span class="ruby-identifier">index</span>

  <span class="ruby-identifier">recv_idx</span> = <span class="ruby-identifier">argc</span> <span class="ruby-comment"># blockarg is not supported</span>
  <span class="ruby-identifier">recv_idx</span> <span class="ruby-operator">+=</span> <span class="ruby-identifier">send_shift</span>
  <span class="ruby-identifier">comptime_recv</span> = <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">peek_at_stack</span>(<span class="ruby-identifier">recv_idx</span>)

  <span class="ruby-comment"># This is a .send call and we need to adjust the stack</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">handle_opt_send_shift_stack</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-value">send_shift:</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># All structs from the same Struct class should have the same</span>
  <span class="ruby-comment"># length. So if our comptime_recv is embedded all runtime</span>
  <span class="ruby-comment"># structs of the same class should be as well, and the same is</span>
  <span class="ruby-comment"># true of the converse.</span>
  <span class="ruby-identifier">embedded</span> = <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">FL_TEST_RAW</span>(<span class="ruby-identifier">comptime_recv</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RSTRUCT_EMBED_LEN_MASK</span>)

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;struct aref&#39;</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-value">1</span>)) <span class="ruby-comment"># recv</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">embedded</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rax</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RStruct</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:ary</span>) <span class="ruby-operator">+</span> (<span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">off</span>)])
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rax</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RStruct</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:heap</span>, <span class="ruby-value">:ptr</span>)])
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rax</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">off</span>])
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">ret</span>, <span class="ruby-value">:rax</span>)

  <span class="ruby-identifier">jump_to_next_insn</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-constant">EndBlock</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_optimized" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_optimized</span><span
                                class="method-args">(jit, ctx, asm, cme, calling, known_recv_class)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_optimized @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_optimized-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5323</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_optimized</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># Not working yet</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_block_arg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">case</span> <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">def</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">optimized</span>.<span class="ruby-identifier">type</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">OPTIMIZED_METHOD_TYPE_SEND</span>
    <span class="ruby-identifier">jit_call_opt_send</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">OPTIMIZED_METHOD_TYPE_CALL</span>
    <span class="ruby-identifier">jit_call_opt_call</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span>, <span class="ruby-identifier">known_recv_class</span>, <span class="ruby-value">send_shift:</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">OPTIMIZED_METHOD_TYPE_BLOCK_CALL</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_block_call</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">OPTIMIZED_METHOD_TYPE_STRUCT_AREF</span>
    <span class="ruby-identifier">jit_call_opt_struct_aref</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>, <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">block_handler</span>, <span class="ruby-identifier">known_recv_class</span>, <span class="ruby-value">send_shift:</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span>)
  <span class="ruby-keyword">in</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">OPTIMIZED_METHOD_TYPE_STRUCT_ASET</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_struct_aset</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_call_symbol" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_call_symbol</span><span
                                class="method-args">(jit, ctx, asm, cme, calling, known_recv_class, flags)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_call_symbol @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_call_symbol-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5496</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_call_symbol</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">known_recv_class</span>, <span class="ruby-identifier">flags</span>)
  <span class="ruby-identifier">flags</span> <span class="ruby-operator">|=</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">|</span> (<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">kw_splat</span> <span class="ruby-operator">?</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KW_SPLAT</span> <span class="ruby-operator">:</span> <span class="ruby-value">0</span>)

  <span class="ruby-identifier">comptime_symbol</span> = <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">peek_at_stack</span>(<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">comptime_symbol</span>.<span class="ruby-identifier">class</span> <span class="ruby-operator">!=</span> <span class="ruby-constant">String</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">static_symbol?</span>(<span class="ruby-identifier">comptime_symbol</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_send_not_sym_or_str</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">mid</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">get_symbol_id</span>(<span class="ruby-identifier">comptime_symbol</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">mid</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_optimized_send_null_mid</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-node">&quot;Guard #{comptime_symbol.inspect} is on stack&quot;</span>)
  <span class="ruby-identifier">class_changed_exit</span> = <span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>), <span class="ruby-value">:send_optimized_send_mid_class_changed</span>)
  <span class="ruby-identifier">jit_guard_known_klass</span>(
    <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_class_of</span>(<span class="ruby-identifier">comptime_symbol</span>), <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>),
    <span class="ruby-constant">StackOpnd</span>[<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>], <span class="ruby-identifier">comptime_symbol</span>, <span class="ruby-identifier">class_changed_exit</span>,
  )
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span>))
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_get_symbol_id</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmp</span>(<span class="ruby-constant">C_RET</span>, <span class="ruby-identifier">mid</span>)
  <span class="ruby-identifier">id_changed_exit</span> = <span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>), <span class="ruby-value">:send_optimized_send_mid_id_changed</span>)
  <span class="ruby-identifier">jit_chain_guard</span>(<span class="ruby-value">:jne</span>, <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">id_changed_exit</span>)

  <span class="ruby-comment"># rb_callable_method_entry_with_refinements</span>
  <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> = <span class="ruby-identifier">flags</span>
  <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">_</span> = <span class="ruby-identifier">jit_search_method</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">mid</span>, <span class="ruby-identifier">calling</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">cme</span> <span class="ruby-operator">==</span> <span class="ruby-constant">CantCompile</span>
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_FCALL</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-keyword">return</span> <span class="ruby-identifier">jit_call_method</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">mid</span>, <span class="ruby-identifier">calling</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">known_recv_class</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">raise</span> <span class="ruby-constant">NotImplementedError</span> <span class="ruby-comment"># unreachable for now</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_caller_setup_arg" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_caller_setup_arg</span><span
                                class="method-args">(jit, ctx, asm, flags)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>CALLER_SETUP_ARG: Return CantCompile if not supported @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_caller_setup_arg-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5671</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_caller_setup_arg</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">flags</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KW_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_args_splat_kw_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># splat is not supported in this path</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_args_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KW_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_args_kw_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KWARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_kwarg</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_direct_jump" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_direct_jump</span><span
                                class="method-args">(iseq, pc, ctx, asm, comment: &#39;jit_direct_jump&#39;)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="jit_direct_jump-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5877</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_direct_jump</span>(<span class="ruby-identifier">iseq</span>, <span class="ruby-identifier">pc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-value">comment:</span> <span class="ruby-string">&#39;jit_direct_jump&#39;</span>)
  <span class="ruby-identifier">branch_stub</span> = <span class="ruby-constant">BranchStub</span>.<span class="ruby-identifier">new</span>(
    <span class="ruby-value">iseq:</span>,
    <span class="ruby-value">shape:</span> <span class="ruby-constant">Default</span>,
    <span class="ruby-value">target0:</span> <span class="ruby-constant">BranchTarget</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">ctx:</span>, <span class="ruby-value">pc:</span>),
  )
  <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">target0</span>.<span class="ruby-identifier">address</span> = <span class="ruby-constant">Assembler</span>.<span class="ruby-identifier">new</span>.<span class="ruby-identifier">then</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ocb_asm</span><span class="ruby-operator">|</span>
    <span class="ruby-ivar">@exit_compiler</span>.<span class="ruby-identifier">compile_branch_stub</span>(<span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">ocb_asm</span>, <span class="ruby-identifier">branch_stub</span>, <span class="ruby-keyword">true</span>)
    <span class="ruby-ivar">@ocb</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">ocb_asm</span>)
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">compile</span> = <span class="ruby-identifier">proc</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">branch_asm</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">branch_asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-identifier">comment</span>)
    <span class="ruby-identifier">branch_asm</span>.<span class="ruby-identifier">stub</span>(<span class="ruby-identifier">branch_stub</span>) <span class="ruby-keyword">do</span>
      <span class="ruby-keyword">case</span> <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">shape</span>
      <span class="ruby-keyword">in</span> <span class="ruby-constant">Default</span>
        <span class="ruby-identifier">branch_asm</span>.<span class="ruby-identifier">jmp</span>(<span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">target0</span>.<span class="ruby-identifier">address</span>)
      <span class="ruby-keyword">in</span> <span class="ruby-constant">Next0</span>
        <span class="ruby-comment"># Just write the block without a jump</span>
      <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">compile</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">asm</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_get_ep" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_get_ep</span><span
                                class="method-args">(asm, level, reg:)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_get_ep @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_get_ep-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4063</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_get_ep</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">level</span>, <span class="ruby-value">reg:</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">reg</span>, [<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:ep</span>)])
  <span class="ruby-identifier">level</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span>
    <span class="ruby-comment"># GET_PREV_EP: ep[VM_ENV_DATA_INDEX_SPECVAL] &amp; ~0x03</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">reg</span>, [<span class="ruby-identifier">reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_ENV_DATA_INDEX_SPECVAL</span>])
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">and</span>(<span class="ruby-identifier">reg</span>, <span class="ruby-operator">~</span><span class="ruby-value">0x03</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_get_lep" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_get_lep</span><span
                                class="method-args">(jit, asm, reg:)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>GET_LEP @param jit [RubyVM::RJIT::JITState] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_get_lep-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4056</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_get_lep</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-value">reg:</span>)
  <span class="ruby-identifier">level</span> = <span class="ruby-identifier">get_lvar_level</span>(<span class="ruby-identifier">jit</span>.<span class="ruby-identifier">iseq</span>)
  <span class="ruby-identifier">jit_get_ep</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">level</span>, <span class="ruby-value">reg:</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_getivar" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_getivar</span><span
                                class="method-args">(jit, ctx, asm, comptime_obj, ivar_id, obj_opnd, obj_yarv_opnd)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_getivar @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_getivar-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4076</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_getivar</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">comptime_obj</span>, <span class="ruby-identifier">ivar_id</span>, <span class="ruby-identifier">obj_opnd</span>, <span class="ruby-identifier">obj_yarv_opnd</span>)
  <span class="ruby-identifier">side_exit</span> = <span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>)
  <span class="ruby-identifier">starting_ctx</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">dup</span> <span class="ruby-comment"># copy for jit_chain_guard</span>

  <span class="ruby-comment"># Guard not special const</span>
  <span class="ruby-keyword">if</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">SPECIAL_CONST_P</span>(<span class="ruby-identifier">comptime_obj</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:getivar_special_const</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-keyword">case</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">BUILTIN_TYPE</span>(<span class="ruby-identifier">comptime_obj</span>)
  <span class="ruby-keyword">when</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">T_OBJECT</span>
    <span class="ruby-comment"># This is the only supported case for now (ROBJECT_IVPTR)</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-comment"># General case. Call rb_ivar_get().</span>
    <span class="ruby-comment"># VALUE rb_ivar_get(VALUE obj, ID id)</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;call rb_ivar_get()&#39;</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-identifier">obj_opnd</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">obj_opnd</span> <span class="ruby-operator">:</span> [<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:self</span>)])
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">ivar_id</span>)

    <span class="ruby-comment"># The function could raise exceptions.</span>
    <span class="ruby-identifier">jit_prepare_routine_call</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>) <span class="ruby-comment"># clobbers obj_opnd and :rax</span>

    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_ivar_get</span>)

    <span class="ruby-keyword">if</span> <span class="ruby-identifier">obj_opnd</span> <span class="ruby-comment"># attr_reader</span>
      <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-comment"># Push the ivar on the stack</span>
    <span class="ruby-identifier">out_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">out_opnd</span>, <span class="ruby-constant">C_RET</span>)

    <span class="ruby-comment"># Jump to next instruction. This allows guard chains to share the same successor.</span>
    <span class="ruby-identifier">jump_to_next_insn</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">EndBlock</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">obj_opnd</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">obj_opnd</span> <span class="ruby-operator">:</span> [<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:self</span>)])
  <span class="ruby-identifier">guard_object_is_heap</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-value">:rax</span>, <span class="ruby-identifier">obj_yarv_opnd</span>, <span class="ruby-value">:getivar_not_heap</span>)

  <span class="ruby-identifier">shape_id</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_shape_get_shape_id</span>(<span class="ruby-identifier">comptime_obj</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">shape_id</span> <span class="ruby-operator">==</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">OBJ_TOO_COMPLEX_SHAPE_ID</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:getivar_too_complex</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;guard shape&#39;</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmp</span>(<span class="ruby-constant">DwordPtr</span>[<span class="ruby-value">:rax</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_shape_id_offset</span>], <span class="ruby-identifier">shape_id</span>)
  <span class="ruby-identifier">jit_chain_guard</span>(<span class="ruby-value">:jne</span>, <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">starting_ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>, <span class="ruby-value">:getivar_megamorphic</span>))

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">obj_opnd</span>
    <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span> <span class="ruby-comment"># pop receiver for attr_reader</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">index</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_shape_get_iv_index</span>(<span class="ruby-identifier">shape_id</span>, <span class="ruby-identifier">ivar_id</span>)
  <span class="ruby-comment"># If there is no IVAR index, then the ivar was undefined</span>
  <span class="ruby-comment"># when we entered the compiler.  That means we can just return</span>
  <span class="ruby-comment"># nil for this shape + iv name</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">index</span>.<span class="ruby-identifier">nil?</span>
    <span class="ruby-identifier">stack_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Nil</span>)
    <span class="ruby-identifier">val_opnd</span> = <span class="ruby-constant">Qnil</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;ROBJECT_IVPTR&#39;</span>)
    <span class="ruby-keyword">if</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">FL_TEST_RAW</span>(<span class="ruby-identifier">comptime_obj</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">ROBJECT_EMBED</span>)
      <span class="ruby-comment"># Access embedded array</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rax</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RObject</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:ary</span>) <span class="ruby-operator">+</span> (<span class="ruby-identifier">index</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>)])
    <span class="ruby-keyword">else</span>
      <span class="ruby-comment"># Pull out an ivar table on heap</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rax</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RObject</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:heap</span>, <span class="ruby-value">:ivptr</span>)])
      <span class="ruby-comment"># Read the table</span>
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rax</span>, <span class="ruby-identifier">index</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>])
    <span class="ruby-keyword">end</span>
    <span class="ruby-identifier">stack_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
    <span class="ruby-identifier">val_opnd</span> = <span class="ruby-value">:rax</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_opnd</span>, <span class="ruby-identifier">val_opnd</span>)

  <span class="ruby-comment"># Let guard chains share the same successor</span>
  <span class="ruby-identifier">jump_to_next_insn</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-constant">EndBlock</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_leaf_builtin_func" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_leaf_builtin_func</span><span
                                class="method-args">(jit, ctx, asm, flags, iseq)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="jit_leaf_builtin_func-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4909</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_leaf_builtin_func</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">flags</span>, <span class="ruby-identifier">iseq</span>)
  <span class="ruby-identifier">builtin_func</span> = <span class="ruby-identifier">builtin_function</span>(<span class="ruby-identifier">iseq</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">builtin_func</span>.<span class="ruby-identifier">nil?</span>
    <span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># this is a .send call not currently supported for builtins</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_OPT_SEND</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">builtin_argc</span> = <span class="ruby-identifier">builtin_func</span>.<span class="ruby-identifier">argc</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">builtin_argc</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span> <span class="ruby-operator">&gt;=</span> <span class="ruby-constant">C_ARGS</span>.<span class="ruby-identifier">size</span>
    <span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;inlined leaf builtin&#39;</span>)

  <span class="ruby-comment"># Skip this if it doesn&#39;t trigger GC</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">body</span>.<span class="ruby-identifier">builtin_attrs</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">BUILTIN_ATTR_NO_GC</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># The callee may allocate, e.g. Integer#abs on a Bignum.</span>
    <span class="ruby-comment"># Save SP for GC, save PC for allocation tracing, and prepare</span>
    <span class="ruby-comment"># for global invalidation after GC&#39;s VM lock contention.</span>
    <span class="ruby-identifier">jit_prepare_routine_call</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Call the builtin func (ec, recv, arg1, arg2, ...)</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], <span class="ruby-constant">EC</span>)

  <span class="ruby-comment"># Copy self and arguments</span>
  (<span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-identifier">builtin_argc</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">stack_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">builtin_argc</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">i</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-identifier">i</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>], <span class="ruby-identifier">stack_opnd</span>)
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-identifier">builtin_argc</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">builtin_func</span>.<span class="ruby-identifier">func_ptr</span>)

  <span class="ruby-comment"># Push the return value</span>
  <span class="ruby-identifier">stack_ret</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">stack_ret</span>, <span class="ruby-constant">C_RET</span>)
  <span class="ruby-keyword">return</span> <span class="ruby-keyword">true</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_protected_callee_ancestry_guard" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_protected_callee_ancestry_guard</span><span
                                class="method-args">(asm, cme, side_exit)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Generate ancestry guard for protected callee. Calls to protected callees only go through when self.is_a?(klass_that_defines_the_callee).</p>

                              <div class="method-source-code" id="jit_protected_callee_ancestry_guard-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4286</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_protected_callee_ancestry_guard</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">side_exit</span>)
  <span class="ruby-comment"># See vm_call_method().</span>
  <span class="ruby-identifier">def_class</span> = <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">defined_class</span>
  <span class="ruby-comment"># Note: PC isn&#39;t written to current control frame as rb_is_kind_of() shouldn&#39;t raise.</span>
  <span class="ruby-comment"># VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass);</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">0</span>], [<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:self</span>)])
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-constant">C_ARGS</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">to_value</span>(<span class="ruby-identifier">def_class</span>))
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">call</span>(<span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_obj_is_kind_of</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">test</span>(<span class="ruby-constant">C_RET</span>, <span class="ruby-constant">C_RET</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">jz</span>(<span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>, <span class="ruby-value">:send_protected_check_failed</span>))
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_push_frame" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_push_frame</span><span
                                class="method-args">(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, iseq: nil, local_size: 0, stack_max: 0, prev_ep: nil, doing_kw_call: nil)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_push_frame</p>

<p>Frame structure: | args | locals | cme/cref | block_handler/prev EP | frame type (EP here) | stack bottom (SP here)</p>

<p>@param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_push_frame-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5545</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_push_frame</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">flags</span>, <span class="ruby-identifier">argc</span>, <span class="ruby-identifier">frame_type</span>, <span class="ruby-identifier">block_handler</span>, <span class="ruby-value">iseq:</span> <span class="ruby-keyword">nil</span>, <span class="ruby-value">local_size:</span> <span class="ruby-value">0</span>, <span class="ruby-value">stack_max:</span> <span class="ruby-value">0</span>, <span class="ruby-value">prev_ep:</span> <span class="ruby-keyword">nil</span>, <span class="ruby-value">doing_kw_call:</span> <span class="ruby-keyword">nil</span>)
  <span class="ruby-comment"># Save caller SP and PC before pushing a callee frame for backtrace and side exits</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;save SP to caller CFP&#39;</span>)
  <span class="ruby-identifier">recv_idx</span> = <span class="ruby-identifier">argc</span> <span class="ruby-comment"># blockarg is already popped</span>
  <span class="ruby-identifier">recv_idx</span> <span class="ruby-operator">+=</span> (<span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-value">:captured</span>) <span class="ruby-operator">?</span> <span class="ruby-value">0</span> <span class="ruby-operator">:</span> <span class="ruby-value">1</span> <span class="ruby-comment"># receiver is not on stack when captured-&gt;self is used</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>
    <span class="ruby-comment"># Skip setting this to SP register. This cfp-&gt;sp will be copied to SP on leave insn.</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-operator">-</span><span class="ruby-identifier">recv_idx</span>)) <span class="ruby-comment"># Pop receiver and arguments to prepare for side exits</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:sp</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-constant">SP</span>, <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_opnd</span>(<span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-operator">-</span><span class="ruby-identifier">recv_idx</span>))
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:sp</span>)], <span class="ruby-constant">SP</span>)
    <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_offset</span> = <span class="ruby-identifier">recv_idx</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">jit_save_pc</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-value">comment:</span> <span class="ruby-string">&#39;save PC to caller CFP&#39;</span>)

  <span class="ruby-identifier">sp_offset</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-value">3</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">local_size</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">doing_kw_call</span> <span class="ruby-operator">?</span> <span class="ruby-value">1</span> <span class="ruby-operator">:</span> <span class="ruby-value">0</span>) <span class="ruby-comment"># callee_sp</span>
  <span class="ruby-identifier">local_size</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;set local variables&#39;</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">local_index</span> = <span class="ruby-identifier">sp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">local_size</span> <span class="ruby-operator">-</span> <span class="ruby-value">3</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">local_index</span>], <span class="ruby-constant">Qnil</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;set up EP with managing data&#39;</span>)
  <span class="ruby-identifier">ep_offset</span> = <span class="ruby-identifier">sp_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>
  <span class="ruby-comment"># ep[-2]: cref_or_me</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">to_i</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">ep_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">2</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-comment"># ep[-1]: block handler or prev env ptr (specval)</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">prev_ep</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">prev_ep</span>.<span class="ruby-identifier">to_i</span> <span class="ruby-operator">|</span> <span class="ruby-value">1</span>) <span class="ruby-comment"># tagged prev ep</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">ep_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-value">:captured</span>
    <span class="ruby-comment"># Set captured-&gt;ep, saving captured in :rcx for captured-&gt;self</span>
    <span class="ruby-identifier">ep_reg</span> = <span class="ruby-value">:rcx</span>
    <span class="ruby-identifier">jit_get_lep</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-value">reg:</span> <span class="ruby-identifier">ep_reg</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rcx</span>, [<span class="ruby-identifier">ep_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_ENV_DATA_INDEX_SPECVAL</span>]) <span class="ruby-comment"># block_handler</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">and</span>(<span class="ruby-value">:rcx</span>, <span class="ruby-operator">~</span><span class="ruby-value">0x3</span>) <span class="ruby-comment"># captured</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rcx</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>]) <span class="ruby-comment"># captured-&gt;ep</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">or</span>(<span class="ruby-value">:rax</span>, <span class="ruby-value">0x1</span>) <span class="ruby-comment"># GC_GUARDED_PTR</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">ep_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_BLOCK_HANDLER_NONE</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">ep_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>)], <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_BLOCK_HANDLER_NONE</span>)
  <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_block_param_proxy</span>
    <span class="ruby-comment"># vm_caller_setup_arg_block: block_code == rb_block_param_proxy</span>
    <span class="ruby-identifier">jit_get_lep</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-value">reg:</span> <span class="ruby-value">:rax</span>) <span class="ruby-comment"># VM_CF_BLOCK_HANDLER: VM_CF_LEP</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rax</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_ENV_DATA_INDEX_SPECVAL</span>]) <span class="ruby-comment"># VM_CF_BLOCK_HANDLER: VM_ENV_BLOCK_HANDLER</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:block_code</span>)], <span class="ruby-value">:rax</span>) <span class="ruby-comment"># reg_cfp-&gt;block_code = handler</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">ep_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>)], <span class="ruby-value">:rax</span>) <span class="ruby-comment"># return handler;</span>
  <span class="ruby-keyword">else</span> <span class="ruby-comment"># assume blockiseq</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">block_handler</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:block_code</span>)], <span class="ruby-value">:rax</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-constant">CFP</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:self</span>)]) <span class="ruby-comment"># VM_CFP_TO_CAPTURED_BLOCK</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">or</span>(<span class="ruby-value">:rax</span>, <span class="ruby-value">1</span>) <span class="ruby-comment"># VM_BH_FROM_ISEQ_BLOCK</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">ep_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-keyword">end</span>
  <span class="ruby-comment"># ep[-0]: ENV_FLAGS</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> (<span class="ruby-identifier">ep_offset</span> <span class="ruby-operator">-</span> <span class="ruby-value">0</span>)], <span class="ruby-identifier">frame_type</span>)

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;set up new frame&#39;</span>)
  <span class="ruby-identifier">cfp_offset</span> = <span class="ruby-operator">-</span><span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">size</span> <span class="ruby-comment"># callee CFP</span>
  <span class="ruby-comment"># For ISEQ, JIT code will set it as needed. However, C func needs 0 there for svar frame detection.</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">nil?</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:pc</span>)], <span class="ruby-value">0</span>)
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">iseq</span>.<span class="ruby-identifier">to_i</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:iseq</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-value">:captured</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-value">:rcx</span>]) <span class="ruby-comment"># captured-&gt;self</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">self_index</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_offset</span> <span class="ruby-operator">-</span> (<span class="ruby-value">1</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">argc</span>) <span class="ruby-comment"># blockarg has been popped</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">self_index</span>])
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:self</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rax</span>, [<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">ep_offset</span>])
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:ep</span>)], <span class="ruby-value">:rax</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:block_code</span>)], <span class="ruby-value">0</span>)
  <span class="ruby-comment"># Update SP register only for ISEQ calls. SP-relative operations should be done above this.</span>
  <span class="ruby-identifier">sp_reg</span> = <span class="ruby-identifier">iseq</span> <span class="ruby-operator">?</span> <span class="ruby-constant">SP</span> <span class="ruby-operator">:</span> <span class="ruby-value">:rax</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-identifier">sp_reg</span>, [<span class="ruby-constant">SP</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">sp_offset</span>])
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:sp</span>)], <span class="ruby-identifier">sp_reg</span>)

  <span class="ruby-comment"># cfp-&gt;jit_return is used only for ISEQs</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">iseq</span>
    <span class="ruby-comment"># The callee might change locals through Kernel#binding and other means.</span>
    <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">clear_local_types</span>

    <span class="ruby-comment"># Stub cfp-&gt;jit_return</span>
    <span class="ruby-identifier">return_ctx</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">dup</span>
    <span class="ruby-identifier">return_ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-identifier">argc</span> <span class="ruby-operator">+</span> ((<span class="ruby-identifier">block_handler</span> <span class="ruby-operator">==</span> <span class="ruby-value">:captured</span>) <span class="ruby-operator">?</span> <span class="ruby-value">0</span> <span class="ruby-operator">:</span> <span class="ruby-value">1</span>)) <span class="ruby-comment"># Pop args and receiver. blockarg has been popped</span>
    <span class="ruby-identifier">return_ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>) <span class="ruby-comment"># push callee&#39;s return value</span>
    <span class="ruby-identifier">return_ctx</span>.<span class="ruby-identifier">sp_offset</span> = <span class="ruby-value">1</span> <span class="ruby-comment"># SP is in the position after popping a receiver and arguments</span>
    <span class="ruby-identifier">return_ctx</span>.<span class="ruby-identifier">chain_depth</span> = <span class="ruby-value">0</span>
    <span class="ruby-identifier">branch_stub</span> = <span class="ruby-constant">BranchStub</span>.<span class="ruby-identifier">new</span>(
      <span class="ruby-value">iseq:</span> <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">iseq</span>,
      <span class="ruby-value">shape:</span> <span class="ruby-constant">Default</span>,
      <span class="ruby-value">target0:</span> <span class="ruby-constant">BranchTarget</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">ctx:</span> <span class="ruby-identifier">return_ctx</span>, <span class="ruby-value">pc:</span> <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">pc</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">insn</span>.<span class="ruby-identifier">len</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>),
    )
    <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">target0</span>.<span class="ruby-identifier">address</span> = <span class="ruby-constant">Assembler</span>.<span class="ruby-identifier">new</span>.<span class="ruby-identifier">then</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ocb_asm</span><span class="ruby-operator">|</span>
      <span class="ruby-ivar">@exit_compiler</span>.<span class="ruby-identifier">compile_branch_stub</span>(<span class="ruby-identifier">return_ctx</span>, <span class="ruby-identifier">ocb_asm</span>, <span class="ruby-identifier">branch_stub</span>, <span class="ruby-keyword">true</span>)
      <span class="ruby-ivar">@ocb</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">ocb_asm</span>)
    <span class="ruby-keyword">end</span>
    <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">compile</span> = <span class="ruby-identifier">proc</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">branch_asm</span><span class="ruby-operator">|</span>
      <span class="ruby-identifier">branch_asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;set jit_return to callee CFP&#39;</span>)
      <span class="ruby-identifier">branch_asm</span>.<span class="ruby-identifier">stub</span>(<span class="ruby-identifier">branch_stub</span>) <span class="ruby-keyword">do</span>
        <span class="ruby-keyword">case</span> <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">shape</span>
        <span class="ruby-keyword">in</span> <span class="ruby-constant">Default</span>
          <span class="ruby-identifier">branch_asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">target0</span>.<span class="ruby-identifier">address</span>)
          <span class="ruby-identifier">branch_asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span> <span class="ruby-operator">+</span> <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_control_frame_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:jit_return</span>)], <span class="ruby-value">:rax</span>)
        <span class="ruby-keyword">end</span>
      <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-identifier">branch_stub</span>.<span class="ruby-identifier">compile</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">asm</span>)
  <span class="ruby-keyword">end</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;switch to callee CFP&#39;</span>)
  <span class="ruby-comment"># Update CFP register only for ISEQ calls</span>
  <span class="ruby-identifier">cfp_reg</span> = <span class="ruby-identifier">iseq</span> <span class="ruby-operator">?</span> <span class="ruby-constant">CFP</span> <span class="ruby-operator">:</span> <span class="ruby-value">:rax</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-identifier">cfp_reg</span>, [<span class="ruby-constant">CFP</span>, <span class="ruby-identifier">cfp_offset</span>])
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-constant">EC</span>, <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_execution_context_t</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:cfp</span>)], <span class="ruby-identifier">cfp_reg</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_search_method" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_search_method</span><span
                                class="method-args">(jit, ctx, asm, mid, calling)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_search_method @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="jit_search_method-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4207</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_search_method</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">mid</span>, <span class="ruby-identifier">calling</span>)
  <span class="ruby-identifier">assert_equal</span>(<span class="ruby-keyword">true</span>, <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">at_current_insn?</span>)

  <span class="ruby-comment"># Generate a side exit</span>
  <span class="ruby-identifier">side_exit</span> = <span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>)

  <span class="ruby-comment"># kw_splat is not supported yet</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_KW_SPLAT</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_kw_splat</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Get a compile-time receiver and its class</span>
  <span class="ruby-identifier">recv_idx</span> = <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">argc</span> <span class="ruby-operator">+</span> (<span class="ruby-identifier">calling</span>.<span class="ruby-identifier">flags</span> <span class="ruby-operator">&amp;</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">VM_CALL_ARGS_BLOCKARG</span> <span class="ruby-operator">!=</span> <span class="ruby-value">0</span> <span class="ruby-operator">?</span> <span class="ruby-value">1</span> <span class="ruby-operator">:</span> <span class="ruby-value">0</span>) <span class="ruby-comment"># blockarg is not popped yet</span>
  <span class="ruby-identifier">recv_idx</span> <span class="ruby-operator">+=</span> <span class="ruby-identifier">calling</span>.<span class="ruby-identifier">send_shift</span>
  <span class="ruby-identifier">comptime_recv</span> = <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">peek_at_stack</span>(<span class="ruby-identifier">recv_idx</span>)
  <span class="ruby-identifier">comptime_recv_klass</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_class_of</span>(<span class="ruby-identifier">comptime_recv</span>)

  <span class="ruby-comment"># Guard the receiver class (part of vm_search_method_fastpath)</span>
  <span class="ruby-identifier">recv_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-identifier">recv_idx</span>)
  <span class="ruby-identifier">megamorphic_exit</span> = <span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>, <span class="ruby-value">:send_klass_megamorphic</span>)
  <span class="ruby-identifier">jit_guard_known_klass</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">comptime_recv_klass</span>, <span class="ruby-identifier">recv_opnd</span>, <span class="ruby-constant">StackOpnd</span>[<span class="ruby-identifier">recv_idx</span>], <span class="ruby-identifier">comptime_recv</span>, <span class="ruby-identifier">megamorphic_exit</span>)

  <span class="ruby-comment"># Do method lookup (vm_cc_cme(cc) != NULL)</span>
  <span class="ruby-identifier">cme</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_callable_method_entry</span>(<span class="ruby-identifier">comptime_recv_klass</span>, <span class="ruby-identifier">mid</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">cme</span>.<span class="ruby-identifier">nil?</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">incr_counter</span>(<span class="ruby-value">:send_missing_cme</span>)
    <span class="ruby-keyword">return</span> <span class="ruby-constant">CantCompile</span> <span class="ruby-comment"># We don&#39;t support vm_call_method_name</span>
  <span class="ruby-keyword">end</span>

  <span class="ruby-comment"># Invalidate on redefinition (part of vm_search_method_fastpath)</span>
  <span class="ruby-constant">Invariants</span>.<span class="ruby-identifier">assume_method_lookup_stable</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">cme</span>)

  <span class="ruby-keyword">return</span> <span class="ruby-identifier">cme</span>, <span class="ruby-identifier">comptime_recv_klass</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-jit_write_iv" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">jit_write_iv</span><span
                                class="method-args">(asm, comptime_receiver, recv_reg, temp_reg, ivar_index, set_value, needs_extension)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="jit_write_iv-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 4159</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">jit_write_iv</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">comptime_receiver</span>, <span class="ruby-identifier">recv_reg</span>, <span class="ruby-identifier">temp_reg</span>, <span class="ruby-identifier">ivar_index</span>, <span class="ruby-identifier">set_value</span>, <span class="ruby-identifier">needs_extension</span>)
  <span class="ruby-comment"># Compile time self is embedded and the ivar index lands within the object</span>
  <span class="ruby-identifier">embed_test_result</span> = <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">FL_TEST_RAW</span>(<span class="ruby-identifier">comptime_receiver</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">ROBJECT_EMBED</span>) <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">needs_extension</span>

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">embed_test_result</span>
    <span class="ruby-comment"># Find the IV offset</span>
    <span class="ruby-identifier">offs</span> = <span class="ruby-constant">C</span>.<span class="ruby-constant">RObject</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:ary</span>) <span class="ruby-operator">+</span> <span class="ruby-identifier">ivar_index</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>

    <span class="ruby-comment"># Write the IV</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;write IV&#39;</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">temp_reg</span>, <span class="ruby-identifier">set_value</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-identifier">recv_reg</span>, <span class="ruby-identifier">offs</span>], <span class="ruby-identifier">temp_reg</span>)
  <span class="ruby-keyword">else</span>
    <span class="ruby-comment"># Compile time value is *not* embedded.</span>

    <span class="ruby-comment"># Get a pointer to the extended table</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">recv_reg</span>, [<span class="ruby-identifier">recv_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RObject</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:heap</span>, <span class="ruby-value">:ivptr</span>)])

    <span class="ruby-comment"># Write the ivar in to the extended table</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&quot;write IV&quot;</span>);
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">temp_reg</span>, <span class="ruby-identifier">set_value</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>([<span class="ruby-identifier">recv_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">ivar_index</span>], <span class="ruby-identifier">temp_reg</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-move_rest_args_to_stack" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">move_rest_args_to_stack</span><span
                                class="method-args">(array, num_args, jit, ctx, asm)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Pushes arguments from an array to the stack. Differs from push splat because the array can have items left over. @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="move_rest_args_to_stack-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5693</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">move_rest_args_to_stack</span>(<span class="ruby-identifier">array</span>, <span class="ruby-identifier">num_args</span>, <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-identifier">side_exit</span> = <span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>)

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;move_rest_args_to_stack&#39;</span>)

  <span class="ruby-comment"># array is :rax</span>
  <span class="ruby-identifier">array_len_opnd</span> = <span class="ruby-value">:rcx</span>
  <span class="ruby-identifier">jit_array_len</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">array</span>, <span class="ruby-identifier">array_len_opnd</span>)

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;Side exit if length is less than required&#39;</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmp</span>(<span class="ruby-identifier">array_len_opnd</span>, <span class="ruby-identifier">num_args</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">jl</span>(<span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>, <span class="ruby-value">:send_iseq_has_rest_and_splat_not_equal</span>))

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;Push arguments from array&#39;</span>)

  <span class="ruby-comment"># Load the address of the embedded array</span>
  <span class="ruby-comment"># (struct RArray *)(obj)-&gt;as.ary</span>
  <span class="ruby-identifier">array_reg</span> = <span class="ruby-identifier">array</span>

  <span class="ruby-comment"># Conditionally load the address of the heap array</span>
  <span class="ruby-comment"># (struct RArray *)(obj)-&gt;as.heap.ptr</span>
  <span class="ruby-identifier">flags_opnd</span> = [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RBasic</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:flags</span>)]
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">test</span>(<span class="ruby-identifier">flags_opnd</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RARRAY_EMBED_FLAG</span>)
  <span class="ruby-identifier">heap_ptr_opnd</span> = [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RArray</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:heap</span>, <span class="ruby-value">:ptr</span>)]
  <span class="ruby-comment"># Load the address of the embedded array</span>
  <span class="ruby-comment"># (struct RArray *)(obj)-&gt;as.ary</span>
  <span class="ruby-identifier">ary_opnd</span> = <span class="ruby-value">:rdx</span> <span class="ruby-comment"># NOTE: array :rax is used after move_rest_args_to_stack too</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rcx</span>, [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RArray</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:ary</span>)])
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">ary_opnd</span>, <span class="ruby-identifier">heap_ptr_opnd</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmovnz</span>(<span class="ruby-identifier">ary_opnd</span>, <span class="ruby-value">:rcx</span>)

  <span class="ruby-identifier">num_args</span>.<span class="ruby-identifier">times</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">top</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rcx</span>, [<span class="ruby-identifier">ary_opnd</span>, <span class="ruby-identifier">i</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>])
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">top</span>, <span class="ruby-value">:rcx</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-push_splat_args" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">push_splat_args</span><span
                                class="method-args">(required_args, jit, ctx, asm)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>vm_caller_setup_arg_splat (+ CALLER_SETUP_ARG): Pushes arguments from an array to the stack that are passed with a splat (i.e. *args). It optimistically compiles to a static size that is the exact number of arguments needed for the function. @param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context] @param asm [RubyVM::RJIT::Assembler]</p>

                              <div class="method-source-code" id="push_splat_args-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5737</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">push_splat_args</span>(<span class="ruby-identifier">required_args</span>, <span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
  <span class="ruby-identifier">side_exit</span> = <span class="ruby-identifier">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>)

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;push_splat_args&#39;</span>)

  <span class="ruby-identifier">array_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_opnd</span>(<span class="ruby-value">0</span>)
  <span class="ruby-identifier">array_stack_opnd</span> = <span class="ruby-constant">StackOpnd</span>[<span class="ruby-value">0</span>]
  <span class="ruby-identifier">array_reg</span> = <span class="ruby-value">:rax</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">array_reg</span>, <span class="ruby-identifier">array_opnd</span>)

  <span class="ruby-identifier">guard_object_is_array</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>, <span class="ruby-identifier">array_reg</span>, <span class="ruby-value">:rcx</span>, <span class="ruby-identifier">array_stack_opnd</span>, <span class="ruby-value">:send_args_splat_not_array</span>)

  <span class="ruby-identifier">array_len_opnd</span> = <span class="ruby-value">:rcx</span>
  <span class="ruby-identifier">jit_array_len</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">array_reg</span>, <span class="ruby-identifier">array_len_opnd</span>)

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;Side exit if length is not equal to remaining args&#39;</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmp</span>(<span class="ruby-identifier">array_len_opnd</span>, <span class="ruby-identifier">required_args</span>)
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">jne</span>(<span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>, <span class="ruby-value">:send_args_splat_length_not_equal</span>))

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;Check last argument is not ruby2keyword hash&#39;</span>)

  <span class="ruby-identifier">ary_opnd</span> = <span class="ruby-value">:rcx</span>
  <span class="ruby-identifier">jit_array_ptr</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">array_reg</span>, <span class="ruby-identifier">ary_opnd</span>) <span class="ruby-comment"># clobbers array_reg</span>

  <span class="ruby-identifier">last_array_value</span> = <span class="ruby-value">:rax</span>
  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">last_array_value</span>, [<span class="ruby-identifier">ary_opnd</span>, (<span class="ruby-identifier">required_args</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>) <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>])

  <span class="ruby-identifier">ruby2_exit</span> = <span class="ruby-identifier">counted_exit</span>(<span class="ruby-identifier">side_exit</span>, <span class="ruby-value">:send_args_splat_ruby2_hash</span>);
  <span class="ruby-identifier">guard_object_is_not_ruby2_keyword_hash</span>(<span class="ruby-identifier">asm</span>, <span class="ruby-identifier">last_array_value</span>, <span class="ruby-value">:rcx</span>, <span class="ruby-identifier">ruby2_exit</span>) <span class="ruby-comment"># clobbers :rax</span>

  <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;Push arguments from array&#39;</span>)
  <span class="ruby-identifier">array_opnd</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_pop</span>(<span class="ruby-value">1</span>)

  <span class="ruby-keyword">if</span> <span class="ruby-identifier">required_args</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">0</span>
    <span class="ruby-comment"># Load the address of the embedded array</span>
    <span class="ruby-comment"># (struct RArray *)(obj)-&gt;as.ary</span>
    <span class="ruby-identifier">array_reg</span> = <span class="ruby-value">:rax</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">array_reg</span>, <span class="ruby-identifier">array_opnd</span>)

    <span class="ruby-comment"># Conditionally load the address of the heap array</span>
    <span class="ruby-comment"># (struct RArray *)(obj)-&gt;as.heap.ptr</span>
    <span class="ruby-identifier">flags_opnd</span> = [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RBasic</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:flags</span>)]
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">test</span>(<span class="ruby-identifier">flags_opnd</span>, <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RARRAY_EMBED_FLAG</span>)
    <span class="ruby-identifier">heap_ptr_opnd</span> = [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RArray</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:heap</span>, <span class="ruby-value">:ptr</span>)]
    <span class="ruby-comment"># Load the address of the embedded array</span>
    <span class="ruby-comment"># (struct RArray *)(obj)-&gt;as.ary</span>
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">lea</span>(<span class="ruby-value">:rcx</span>, [<span class="ruby-identifier">array_reg</span>, <span class="ruby-constant">C</span>.<span class="ruby-constant">RArray</span>.<span class="ruby-identifier">offsetof</span>(<span class="ruby-value">:as</span>, <span class="ruby-value">:ary</span>)])
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rax</span>, <span class="ruby-identifier">heap_ptr_opnd</span>)
    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">cmovnz</span>(<span class="ruby-value">:rax</span>, <span class="ruby-value">:rcx</span>)
    <span class="ruby-identifier">ary_opnd</span> = <span class="ruby-value">:rax</span>

    (<span class="ruby-value">0</span><span class="ruby-operator">...</span><span class="ruby-identifier">required_args</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
      <span class="ruby-identifier">top</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">stack_push</span>(<span class="ruby-constant">Type</span><span class="ruby-operator">::</span><span class="ruby-constant">Unknown</span>)
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-value">:rcx</span>, [<span class="ruby-identifier">ary_opnd</span>, <span class="ruby-identifier">i</span> <span class="ruby-operator">*</span> <span class="ruby-constant">C</span>.<span class="ruby-constant">VALUE</span>.<span class="ruby-identifier">size</span>])
      <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">mov</span>(<span class="ruby-identifier">top</span>, <span class="ruby-value">:rcx</span>)
    <span class="ruby-keyword">end</span>

    <span class="ruby-identifier">asm</span>.<span class="ruby-identifier">comment</span>(<span class="ruby-string">&#39;end push_each&#39;</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-shape_too_complex-3F" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">shape_too_complex?</span><span
                                class="method-args">(obj)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="shape_too_complex-3F-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5861</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">shape_too_complex?</span>(<span class="ruby-identifier">obj</span>)
  <span class="ruby-constant">C</span>.<span class="ruby-identifier">rb_shape_get_shape_id</span>(<span class="ruby-identifier">obj</span>) <span class="ruby-operator">==</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">OBJ_TOO_COMPLEX_SHAPE_ID</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-side_exit" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">side_exit</span><span
                                class="method-args">(jit, ctx)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>@param jit [RubyVM::RJIT::JITState] @param ctx [RubyVM::RJIT::Context]</p>

                              <div class="method-source-code" id="side_exit-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5903</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">side_exit</span>(<span class="ruby-identifier">jit</span>, <span class="ruby-identifier">ctx</span>)
  <span class="ruby-comment"># We use the latest ctx.sp_offset to generate a side exit to tolerate sp_offset changes by jit_save_sp.</span>
  <span class="ruby-comment"># However, we want to simulate an old stack_size when we take a side exit. We do that by adjusting the</span>
  <span class="ruby-comment"># sp_offset because gen_outlined_exit uses ctx.sp_offset to move SP.</span>
  <span class="ruby-identifier">ctx</span> = <span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">with_stack_size</span>(<span class="ruby-identifier">jit</span>.<span class="ruby-identifier">stack_size_for_pc</span>)

  <span class="ruby-identifier">jit</span>.<span class="ruby-identifier">side_exit_for_pc</span>[<span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">sp_offset</span>] <span class="ruby-operator">||=</span> <span class="ruby-constant">Assembler</span>.<span class="ruby-identifier">new</span>.<span class="ruby-identifier">then</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">asm</span><span class="ruby-operator">|</span>
    <span class="ruby-ivar">@exit_compiler</span>.<span class="ruby-identifier">compile_side_exit</span>(<span class="ruby-identifier">jit</span>.<span class="ruby-identifier">pc</span>, <span class="ruby-identifier">ctx</span>, <span class="ruby-identifier">asm</span>)
    <span class="ruby-ivar">@ocb</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">asm</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-static_symbol-3F" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">static_symbol?</span><span
                                class="method-args">(obj)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="static_symbol-3F-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5852</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">static_symbol?</span>(<span class="ruby-identifier">obj</span>)
  (<span class="ruby-constant">C</span>.<span class="ruby-identifier">to_value</span>(<span class="ruby-identifier">obj</span>) <span class="ruby-operator">&amp;</span> <span class="ruby-value">0xff</span>) <span class="ruby-operator">==</span> <span class="ruby-constant">C</span><span class="ruby-operator">::</span><span class="ruby-constant">RUBY_SYMBOL_FLAG</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-symbol-3F" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">symbol?</span><span
                                class="method-args">(obj)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="symbol-3F-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5848</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">symbol?</span>(<span class="ruby-identifier">obj</span>)
  <span class="ruby-identifier">static_symbol?</span>(<span class="ruby-identifier">obj</span>) <span class="ruby-operator">||</span> <span class="ruby-identifier">dynamic_symbol?</span>(<span class="ruby-identifier">obj</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-to_value" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">to_value</span><span
                                class="method-args">(obj)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="to_value-source">
            <pre><span class="ruby-comment"># File ruby_vm/rjit/insn_compiler.rb, line 5926</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">to_value</span>(<span class="ruby-identifier">obj</span>)
  <span class="ruby-constant">GC_REFS</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">obj</span>
  <span class="ruby-constant">C</span>.<span class="ruby-identifier">to_value</span>(<span class="ruby-identifier">obj</span>)
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                          </section>

              </section>
              </main>



            </div>  <!--  class='wrapper hdiv' -->


<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a></p>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.4.0.</p>
<p>Based on <a href="https://github.com/ged/darkfish/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.</p>

  
    <p><p><a href="https://ruby-doc.org">Ruby-doc.org</a> is provided by <a href="https://jamesbritt.com">James Britt</a> and <a href="https://neurogami.com">Neurogami</a>.</p><p><a href="https://jamesbritt.bandcamp.com/">Maximum R+D</a>.  </p>
</p>
  
  </footer>

<script type="text/javascript">


  let ads  = $("#carbonads-container").children().detach();


  function swapMode() {
    var cookieName = 'darkmode';
    var cssDarkmode = Cookies.get(cookieName);
    console.log("***** swapMode! " + cssDarkmode + " *****");


    if (cssDarkmode == "true") {
      console.log("We have dark mode, set the css to light ...");
      $('#rdoccss').attr("href", defaultModeCssHref);
      $('#cssSelect').text("Dark mode");
      cssDarkmode = "false";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    } else {
      console.log("We not have dark mode, set the css to dark ...");
      $('#rdoccss').attr("href", darkModeCsseHref);
      $('#cssSelect').text("Light mode");
      cssDarkmode = "true";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    }

    console.log("  --------------- ");
  }


const vueCssApp = new Vue({
el: '#menubar',
data: {
isDark: false
},
methods: {
toggleClass: function(event){
this.isDark = !this.isDark;
}
}
})

const vueApp = new Vue({
el: '#vapp',
data: { 
isOpen: true
},

mounted() {
this.handleResize();
this.manage_mob_classes();
window.addEventListener('resize', this.handleResize)
//this.isOpen !=  (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
created() {
//manage_mob_classes();
},

methods : {
isMobile() {
  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},

  handleResize() {
    if (!this.isMobile()) {
      this.isOpen = window.innerWidth > 800;
    }
  },

  manage_mob_classes() {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
      $("nav").addClass("mob_nav");
      $("main").addClass("mob_main");
      $("#extraz").addClass("mob_extraz");
      $("#carbonads-container").addClass("mob_carbonads-container");
      this.isOpen  = false;
    } else {
      $("nav").removeClass("mob_nav") 
        $("main").removeClass("mob_main");
      $("#extraz").removeClass("mob_extraz");
      $("#carbonads-container").removeClass("mob_carbonads-container");
      this.isOpen  = true;
    }
  },

  toggleNav() {
    this.isOpen =! this.isOpen ;
    // alert("Toggle nav!");
    console.log("toggleNav() click: " + this.isOpen );
  }
}
})

$("#carbonads-container").append(ads);


$(function() {

    var darkmode = Cookies.get("darkmode");
    console.log("Document ready: " + darkmode);

    if ( darkmode  == "true" ) {
      $('#cssSelect').text("Light mode");
    } else {
      $('#cssSelect').text("Dark mode");
     }

    $('body').css('display','block');
    });

</script>

    
  </body> 
</html>

